1; RUN: opt -S -jump-threading %s | FileCheck %s 2; When simplify a branch based on LVI predicates, we should replace the 3; comparison itself with a constant (when possible) in case it's otherwise used. 4 5define i32 @test(i32* %p) { 6; CHECK-LABEL: @test 7; CHECK: icmp eq 8; CHECK-NEXT: br i1 %cmp, label %exit2, label %exit1 9; CHECK-NOT: icmp ne 10entry: 11 %cmp = icmp eq i32* %p, null 12 br i1 %cmp, label %is_null, label %not_null 13is_null: 14 %cmp2 = icmp ne i32* %p, null 15 br i1 %cmp2, label %exit1, label %exit2 16not_null: 17 %cmp3 = icmp ne i32* %p, null 18 br i1 %cmp3, label %exit1, label %exit2 19exit1: 20 ret i32 0 21exit2: 22 ret i32 1 23} 24 25declare void @use(i1) 26 27; It would not be legal to replace %cmp2 (well, in this case it actually is, 28; but that's a CSE problem, not a LVI/jump threading problem) 29define i32 @test_negative(i32* %p) { 30; CHECK-LABEL: @test 31; CHECK: icmp ne 32; CHECK: icmp eq 33; CHECK-NEXT: br i1 %cmp, label %exit2, label %exit1 34; CHECK-NOT: icmp ne 35entry: 36 %cmp2 = icmp ne i32* %p, null 37 call void @use(i1 %cmp2) 38 %cmp = icmp eq i32* %p, null 39 br i1 %cmp, label %is_null, label %not_null 40is_null: 41 br i1 %cmp2, label %exit1, label %exit2 42not_null: 43 br i1 %cmp2, label %exit1, label %exit2 44exit1: 45 ret i32 0 46exit2: 47 ret i32 1 48} 49 50; In this case, we can remove cmp2 because it's otherwise unused 51define i32 @test2(i32* %p) { 52; CHECK-LABEL: @test 53; CHECK-LABEL: entry: 54; CHECK-NEXT: icmp eq 55; CHECK-NEXT: br i1 %cmp, label %exit2, label %exit1 56; CHECK-NOT: icmp ne 57entry: 58 %cmp2 = icmp ne i32* %p, null 59 %cmp = icmp eq i32* %p, null 60 br i1 %cmp, label %is_null, label %not_null 61is_null: 62 br i1 %cmp2, label %exit1, label %exit2 63not_null: 64 br i1 %cmp2, label %exit1, label %exit2 65exit1: 66 ret i32 0 67exit2: 68 ret i32 1 69} 70