1; RUN: opt -jump-threading -S < %s | FileCheck %s 2 3declare void @side_effect(i32) 4 5define void @test0(i32 %i, i32 %len) { 6; CHECK-LABEL: @test0( 7 entry: 8 call void @side_effect(i32 0) 9 %i.inc = add nuw i32 %i, 1 10 %c0 = icmp ult i32 %i.inc, %len 11 br i1 %c0, label %left, label %right 12 13 left: 14; CHECK: entry: 15; CHECK: br i1 %c0, label %left0, label %right 16 17; CHECK: left0: 18; CHECK: call void @side_effect 19; CHECK-NOT: br i1 %c1 20; CHECK: call void @side_effect 21 call void @side_effect(i32 0) 22 %c1 = icmp ult i32 %i, %len 23 br i1 %c1, label %left0, label %right 24 25 left0: 26 call void @side_effect(i32 0) 27 ret void 28 29 right: 30 %t = phi i32 [ 1, %left ], [ 2, %entry ] 31 call void @side_effect(i32 %t) 32 ret void 33} 34 35define void @test1(i32 %i, i32 %len) { 36; CHECK-LABEL: @test1( 37 entry: 38 call void @side_effect(i32 0) 39 %i.inc = add nsw i32 %i, 1 40 %c0 = icmp slt i32 %i.inc, %len 41 br i1 %c0, label %left, label %right 42 43 left: 44; CHECK: entry: 45; CHECK: br i1 %c0, label %left0, label %right 46 47; CHECK: left0: 48; CHECK: call void @side_effect 49; CHECK-NOT: br i1 %c1 50; CHECK: call void @side_effect 51 call void @side_effect(i32 0) 52 %c1 = icmp slt i32 %i, %len 53 br i1 %c1, label %left0, label %right 54 55 left0: 56 call void @side_effect(i32 0) 57 ret void 58 59 right: 60 %t = phi i32 [ 1, %left ], [ 2, %entry ] 61 call void @side_effect(i32 %t) 62 ret void 63} 64 65define void @test2(i32 %i, i32 %len, i1* %c.ptr) { 66; CHECK-LABEL: @test2( 67 68; CHECK: entry: 69; CHECK: br i1 %c0, label %cont, label %right 70; CHECK: cont: 71; CHECK: br i1 %c, label %left0, label %right 72; CHECK: left0: 73; CHECK: call void @side_effect(i32 0) 74; CHECK: call void @side_effect(i32 0) 75 entry: 76 call void @side_effect(i32 0) 77 %i.inc = add nsw i32 %i, 1 78 %c0 = icmp slt i32 %i.inc, %len 79 br i1 %c0, label %cont, label %right 80 81 cont: 82 %c = load i1, i1* %c.ptr 83 br i1 %c, label %left, label %right 84 85 left: 86 call void @side_effect(i32 0) 87 %c1 = icmp slt i32 %i, %len 88 br i1 %c1, label %left0, label %right 89 90 left0: 91 call void @side_effect(i32 0) 92 ret void 93 94 right: 95 %t = phi i32 [ 1, %left ], [ 2, %entry ], [ 3, %cont ] 96 call void @side_effect(i32 %t) 97 ret void 98} 99 100; A s<= B implies A s> B is false. 101; CHECK-LABEL: @test3( 102; CHECK: entry: 103; CHECK: br i1 %cmp, label %if.end, label %if.end3 104; CHECK-NOT: br i1 %cmp1, label %if.then2, label %if.end 105; CHECK-NOT: call void @side_effect(i32 0) 106; CHECK: br label %if.end3 107; CHECK: ret void 108 109define void @test3(i32 %a, i32 %b) { 110entry: 111 %cmp = icmp sle i32 %a, %b 112 br i1 %cmp, label %if.then, label %if.end3 113 114if.then: 115 %cmp1 = icmp sgt i32 %a, %b 116 br i1 %cmp1, label %if.then2, label %if.end 117 118if.then2: 119 call void @side_effect(i32 0) 120 br label %if.end 121 122if.end: 123 br label %if.end3 124 125if.end3: 126 ret void 127} 128 129declare void @is(i1) 130 131; If A >=s B is false then A <=s B is implied true. 132; CHECK-LABEL: @test_sge_sle 133; CHECK: call void @is(i1 true) 134; CHECK-NOT: call void @is(i1 false) 135define void @test_sge_sle(i32 %a, i32 %b) { 136 %cmp1 = icmp sge i32 %a, %b 137 br i1 %cmp1, label %untaken, label %taken 138 139taken: 140 %cmp2 = icmp sle i32 %a, %b 141 br i1 %cmp2, label %istrue, label %isfalse 142 143istrue: 144 call void @is(i1 true) 145 ret void 146 147isfalse: 148 call void @is(i1 false) 149 ret void 150 151untaken: 152 ret void 153} 154 155; If A <=s B is false then A <=s B is implied false. 156; CHECK-LABEL: @test_sle_sle 157; CHECK-NOT: call void @is(i1 true) 158; CHECK: call void @is(i1 false) 159define void @test_sle_sle(i32 %a, i32 %b) { 160 %cmp1 = icmp sle i32 %a, %b 161 br i1 %cmp1, label %untaken, label %taken 162 163taken: 164 %cmp2 = icmp sle i32 %a, %b 165 br i1 %cmp2, label %istrue, label %isfalse 166 167istrue: 168 call void @is(i1 true) 169 ret void 170 171isfalse: 172 call void @is(i1 false) 173 ret void 174 175untaken: 176 ret void 177} 178