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 5 define 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 10 entry: 11 %cmp = icmp eq i32* %p, null 12 br i1 %cmp, label %is_null, label %not_null 13 is_null: 14 %cmp2 = icmp ne i32* %p, null 15 br i1 %cmp2, label %exit1, label %exit2 16 not_null: 17 %cmp3 = icmp ne i32* %p, null 18 br i1 %cmp3, label %exit1, label %exit2 19 exit1: 20 ret i32 0 21 exit2: 22 ret i32 1 23 } 24 25 declare 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) 29 define 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 35 entry: 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 40 is_null: 41 br i1 %cmp2, label %exit1, label %exit2 42 not_null: 43 br i1 %cmp2, label %exit1, label %exit2 44 exit1: 45 ret i32 0 46 exit2: 47 ret i32 1 48 } 49 50 ; In this case, we can remove cmp2 because it's otherwise unused 51 define 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 57 entry: 58 %cmp2 = icmp ne i32* %p, null 59 %cmp = icmp eq i32* %p, null 60 br i1 %cmp, label %is_null, label %not_null 61 is_null: 62 br i1 %cmp2, label %exit1, label %exit2 63 not_null: 64 br i1 %cmp2, label %exit1, label %exit2 65 exit1: 66 ret i32 0 67 exit2: 68 ret i32 1 69 } 70