1ad5a84c8SPhilip Reames; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2ad5a84c8SPhilip Reames; RUN: opt < %s -loop-predication -S | FileCheck %s 3ad5a84c8SPhilip Reames 4ad5a84c8SPhilip Reamesdeclare void @prevent_merging() 5ad5a84c8SPhilip Reames 6ad5a84c8SPhilip Reames; Base case - with side effects in loop 7ad5a84c8SPhilip Reamesdefine i32 @test1(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 8ad5a84c8SPhilip Reames; CHECK-LABEL: @test1( 9ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 10ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 11*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 12*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 13*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 14*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 15*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 16*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 17*b46c085dSRoman Lebedev; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 18ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 19ad5a84c8SPhilip Reames; CHECK: deopt: 20ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 21ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 22ad5a84c8SPhilip Reames; CHECK: loop.preheader: 23ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 24ad5a84c8SPhilip Reames; CHECK: loop: 25ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 26ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 27ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 28ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 29ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 30ad5a84c8SPhilip Reames; CHECK: deopt2: 31ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 32ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 33ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 34ad5a84c8SPhilip Reames; CHECK: guarded: 35ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 36ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 37ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 38*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 39ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 40ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 41ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 42ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 43ad5a84c8SPhilip Reames; CHECK: exit: 44ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 45ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 46ad5a84c8SPhilip Reames; 47ad5a84c8SPhilip Reamesentry: 48ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 49ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 50ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 51ad5a84c8SPhilip Reames 52ad5a84c8SPhilip Reamesdeopt: 53ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 54ad5a84c8SPhilip Reames ret i32 %deoptret 55ad5a84c8SPhilip Reames 56ad5a84c8SPhilip Reamesloop.preheader: 57ad5a84c8SPhilip Reames br label %loop 58ad5a84c8SPhilip Reames 59ad5a84c8SPhilip Reamesloop: 60ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 61ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 62ad5a84c8SPhilip Reames call void @unknown() 63ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 64ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 65ad5a84c8SPhilip Reames 66ad5a84c8SPhilip Reamesdeopt2: 67ad5a84c8SPhilip Reames call void @unknown() 68ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 69ad5a84c8SPhilip Reames ret i32 %deoptret2 70ad5a84c8SPhilip Reames 71ad5a84c8SPhilip Reamesguarded: 72ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 73ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 74ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 75ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 76ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 77ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 78ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %n 79ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 80ad5a84c8SPhilip Reames 81ad5a84c8SPhilip Reamesexit: 82ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 83ad5a84c8SPhilip Reames ret i32 %result 84ad5a84c8SPhilip Reames} 85ad5a84c8SPhilip Reames 86ad5a84c8SPhilip Reames 87ad5a84c8SPhilip Reames 88ad5a84c8SPhilip Reamesdefine i32 @test_non_canonical(i32* %array, i32 %length, i1 %cond_0) { 89ad5a84c8SPhilip Reames; CHECK-LABEL: @test_non_canonical( 90ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 91ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 92*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LENGTH:%.*]], i32 1) 93*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 94*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH]], i32 [[TMP0]]) 95*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 96*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 97*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 98*b46c085dSRoman Lebedev; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 99ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 100ad5a84c8SPhilip Reames; CHECK: deopt: 101ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 102ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 103ad5a84c8SPhilip Reames; CHECK: loop.preheader: 104ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 105ad5a84c8SPhilip Reames; CHECK: loop: 106ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 107ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 108ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 109ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 110ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 111ad5a84c8SPhilip Reames; CHECK: deopt2: 112ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 113ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 114ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 115ad5a84c8SPhilip Reames; CHECK: guarded: 116ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 117ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 118ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 119*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 120ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 121ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 122ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]] 123ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 124ad5a84c8SPhilip Reames; CHECK: exit: 125ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 126ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 127ad5a84c8SPhilip Reames; 128ad5a84c8SPhilip Reamesentry: 129ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 130ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 131ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 132ad5a84c8SPhilip Reames 133ad5a84c8SPhilip Reamesdeopt: 134ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 135ad5a84c8SPhilip Reames ret i32 %deoptret 136ad5a84c8SPhilip Reames 137ad5a84c8SPhilip Reamesloop.preheader: 138ad5a84c8SPhilip Reames br label %loop 139ad5a84c8SPhilip Reames 140ad5a84c8SPhilip Reamesloop: 141ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 142ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 143ad5a84c8SPhilip Reames call void @unknown() 144ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 145ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 146ad5a84c8SPhilip Reames 147ad5a84c8SPhilip Reamesdeopt2: 148ad5a84c8SPhilip Reames call void @unknown() 149ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 150ad5a84c8SPhilip Reames ret i32 %deoptret2 151ad5a84c8SPhilip Reames 152ad5a84c8SPhilip Reamesguarded: 153ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 154ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 155ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 156ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 157ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 158ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 159ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %length 160ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 161ad5a84c8SPhilip Reames 162ad5a84c8SPhilip Reamesexit: 163ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 164ad5a84c8SPhilip Reames ret i32 %result 165ad5a84c8SPhilip Reames} 166ad5a84c8SPhilip Reames 167ad5a84c8SPhilip Reames 168ad5a84c8SPhilip Reamesdefine i32 @test_two_range_checks(i32* %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) { 169ad5a84c8SPhilip Reames; CHECK-LABEL: @test_two_range_checks( 170ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 171ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 172*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_2:%.*]], i32 [[LENGTH_1:%.*]]) 173*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 174*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 175*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[TMP0]]) 176*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]] 177*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 178*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 179*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]] 180ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]] 181*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]] 182*b46c085dSRoman Lebedev; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]] 183ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 184ad5a84c8SPhilip Reames; CHECK: deopt: 185ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 186ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 187ad5a84c8SPhilip Reames; CHECK: loop.preheader: 188ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 189ad5a84c8SPhilip Reames; CHECK: loop: 190ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 191ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 192ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 193ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] 194ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0 195ad5a84c8SPhilip Reames; CHECK: deopt2: 196ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 197ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 198ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 199ad5a84c8SPhilip Reames; CHECK: guarded: 200ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] 201ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 202ad5a84c8SPhilip Reames; CHECK: deopt3: 203ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 204ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 205ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET3]] 206ad5a84c8SPhilip Reames; CHECK: guarded2: 207ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 208ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 209ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 210*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 211ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 212ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 213ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 214ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 215ad5a84c8SPhilip Reames; CHECK: exit: 216ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 217ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 218ad5a84c8SPhilip Reames; 219ad5a84c8SPhilip Reamesentry: 220ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 221ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 222ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 223ad5a84c8SPhilip Reames 224ad5a84c8SPhilip Reamesdeopt: 225ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 226ad5a84c8SPhilip Reames ret i32 %deoptret 227ad5a84c8SPhilip Reames 228ad5a84c8SPhilip Reamesloop.preheader: 229ad5a84c8SPhilip Reames br label %loop 230ad5a84c8SPhilip Reames 231ad5a84c8SPhilip Reamesloop: 232ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 233ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 234ad5a84c8SPhilip Reames call void @unknown() 235ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length.1 236ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 237ad5a84c8SPhilip Reames 238ad5a84c8SPhilip Reamesdeopt2: 239ad5a84c8SPhilip Reames call void @unknown() 240ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 241ad5a84c8SPhilip Reames ret i32 %deoptret2 242ad5a84c8SPhilip Reames 243ad5a84c8SPhilip Reamesguarded: 244ad5a84c8SPhilip Reames %within.bounds2 = icmp ult i32 %i, %length.2 245ad5a84c8SPhilip Reames br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0 246ad5a84c8SPhilip Reames 247ad5a84c8SPhilip Reamesdeopt3: 248ad5a84c8SPhilip Reames call void @unknown() 249ad5a84c8SPhilip Reames %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 250ad5a84c8SPhilip Reames ret i32 %deoptret3 251ad5a84c8SPhilip Reames 252ad5a84c8SPhilip Reamesguarded2: 253ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 254ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 255ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 256ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 257ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 258ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 259ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %n 260ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 261ad5a84c8SPhilip Reames 262ad5a84c8SPhilip Reamesexit: 263ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded2 ] 264ad5a84c8SPhilip Reames ret i32 %result 265ad5a84c8SPhilip Reames} 266ad5a84c8SPhilip Reames 267ad5a84c8SPhilip Reames@G = external global i32 268ad5a84c8SPhilip Reames 269ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_exit(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 270ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_exit( 271ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 272ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 273ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 274ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 275ad5a84c8SPhilip Reames; CHECK: deopt: 276ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 277ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 278ad5a84c8SPhilip Reames; CHECK: loop.preheader: 279ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 280ad5a84c8SPhilip Reames; CHECK: loop: 281ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 282ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 283ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 284*b46c085dSRoman Lebedev; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G, align 4 285ad5a84c8SPhilip Reames; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0 286ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 287ad5a84c8SPhilip Reames; CHECK: deopt3: 288ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 289ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 290ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET3]] 291ad5a84c8SPhilip Reames; CHECK: guarded2: 292ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 293ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 294ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 295*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 296ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 297ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 298ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N:%.*]] 299ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 300ad5a84c8SPhilip Reames; CHECK: exit: 301ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 302ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 303ad5a84c8SPhilip Reames; 304ad5a84c8SPhilip Reamesentry: 305ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 306ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 307ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 308ad5a84c8SPhilip Reames 309ad5a84c8SPhilip Reamesdeopt: 310ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 311ad5a84c8SPhilip Reames ret i32 %deoptret 312ad5a84c8SPhilip Reames 313ad5a84c8SPhilip Reamesloop.preheader: 314ad5a84c8SPhilip Reames br label %loop 315ad5a84c8SPhilip Reames 316ad5a84c8SPhilip Reamesloop: 317ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 318ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 319ad5a84c8SPhilip Reames call void @unknown() 320ad5a84c8SPhilip Reames %vol = load volatile i32, i32* @G 321ad5a84c8SPhilip Reames %unknown = icmp eq i32 %vol, 0 322ad5a84c8SPhilip Reames br i1 %unknown, label %guarded2, label %deopt3, !prof !0 323ad5a84c8SPhilip Reames 324ad5a84c8SPhilip Reamesdeopt3: 325ad5a84c8SPhilip Reames call void @unknown() 326ad5a84c8SPhilip Reames %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 327ad5a84c8SPhilip Reames ret i32 %deoptret3 328ad5a84c8SPhilip Reames 329ad5a84c8SPhilip Reamesguarded2: 330ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 331ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 332ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 333ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 334ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 335ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 336ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %n 337ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 338ad5a84c8SPhilip Reames 339ad5a84c8SPhilip Reamesexit: 340ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded2 ] 341ad5a84c8SPhilip Reames ret i32 %result 342ad5a84c8SPhilip Reames} 343ad5a84c8SPhilip Reames 344ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_exit2(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 345ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_exit2( 346ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 347ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 348*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 349*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 350*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 351*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 352*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 353*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 354*b46c085dSRoman Lebedev; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 355ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 356ad5a84c8SPhilip Reames; CHECK: deopt: 357ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 358ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 359ad5a84c8SPhilip Reames; CHECK: loop.preheader: 360ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 361ad5a84c8SPhilip Reames; CHECK: loop: 362ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 363ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 364ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 365ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 366ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0 367ad5a84c8SPhilip Reames; CHECK: deopt2: 368ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 369ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 370ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 371ad5a84c8SPhilip Reames; CHECK: guarded: 372*b46c085dSRoman Lebedev; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G, align 4 373ad5a84c8SPhilip Reames; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0 374ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 375ad5a84c8SPhilip Reames; CHECK: deopt3: 376ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 377ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 378ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET3]] 379ad5a84c8SPhilip Reames; CHECK: guarded2: 380ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 381ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 382ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 383*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 384ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 385ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 386ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 387ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 388ad5a84c8SPhilip Reames; CHECK: exit: 389ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 390ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 391ad5a84c8SPhilip Reames; 392ad5a84c8SPhilip Reamesentry: 393ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 394ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 395ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 396ad5a84c8SPhilip Reames 397ad5a84c8SPhilip Reamesdeopt: 398ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 399ad5a84c8SPhilip Reames ret i32 %deoptret 400ad5a84c8SPhilip Reames 401ad5a84c8SPhilip Reamesloop.preheader: 402ad5a84c8SPhilip Reames br label %loop 403ad5a84c8SPhilip Reames 404ad5a84c8SPhilip Reamesloop: 405ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 406ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 407ad5a84c8SPhilip Reames call void @unknown() 408ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 409ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 410ad5a84c8SPhilip Reames 411ad5a84c8SPhilip Reamesdeopt2: 412ad5a84c8SPhilip Reames call void @unknown() 413ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 414ad5a84c8SPhilip Reames ret i32 %deoptret2 415ad5a84c8SPhilip Reames 416ad5a84c8SPhilip Reamesguarded: 417ad5a84c8SPhilip Reames %vol = load volatile i32, i32* @G 418ad5a84c8SPhilip Reames %unknown = icmp eq i32 %vol, 0 419ad5a84c8SPhilip Reames br i1 %unknown, label %guarded2, label %deopt3, !prof !0 420ad5a84c8SPhilip Reames 421ad5a84c8SPhilip Reamesdeopt3: 422ad5a84c8SPhilip Reames call void @unknown() 423ad5a84c8SPhilip Reames %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 424ad5a84c8SPhilip Reames ret i32 %deoptret3 425ad5a84c8SPhilip Reames 426ad5a84c8SPhilip Reamesguarded2: 427ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 428ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 429ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 430ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 431ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 432ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 433ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %n 434ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 435ad5a84c8SPhilip Reames 436ad5a84c8SPhilip Reamesexit: 437ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded2 ] 438ad5a84c8SPhilip Reames ret i32 %result 439ad5a84c8SPhilip Reames} 440ad5a84c8SPhilip Reames 441ad5a84c8SPhilip Reames 442ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_latch(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 443ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_latch( 444ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 445ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 446ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 447ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 448ad5a84c8SPhilip Reames; CHECK: deopt: 449ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 450ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 451ad5a84c8SPhilip Reames; CHECK: loop.preheader: 452ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 453ad5a84c8SPhilip Reames; CHECK: loop: 454ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 455ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 456ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 457ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 458ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 459ad5a84c8SPhilip Reames; CHECK: deopt2: 460ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 461ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 462ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 463ad5a84c8SPhilip Reames; CHECK: guarded: 464ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 465ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 466ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 467*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 468ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 469ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 470*b46c085dSRoman Lebedev; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G, align 4 471ad5a84c8SPhilip Reames; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0 472ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[UNKNOWN]], label [[LOOP]], label [[EXIT:%.*]] 473ad5a84c8SPhilip Reames; CHECK: exit: 474ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 475ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 476ad5a84c8SPhilip Reames; 477ad5a84c8SPhilip Reamesentry: 478ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 479ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 480ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 481ad5a84c8SPhilip Reames 482ad5a84c8SPhilip Reamesdeopt: 483ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 484ad5a84c8SPhilip Reames ret i32 %deoptret 485ad5a84c8SPhilip Reames 486ad5a84c8SPhilip Reamesloop.preheader: 487ad5a84c8SPhilip Reames br label %loop 488ad5a84c8SPhilip Reames 489ad5a84c8SPhilip Reamesloop: 490ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 491ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 492ad5a84c8SPhilip Reames call void @unknown() 493ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 494ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 495ad5a84c8SPhilip Reames 496ad5a84c8SPhilip Reamesdeopt2: 497ad5a84c8SPhilip Reames call void @unknown() 498ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 499ad5a84c8SPhilip Reames ret i32 %deoptret2 500ad5a84c8SPhilip Reames 501ad5a84c8SPhilip Reamesguarded: 502ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 503ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 504ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 505ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 506ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 507ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 508ad5a84c8SPhilip Reames %vol = load volatile i32, i32* @G 509ad5a84c8SPhilip Reames %unknown = icmp eq i32 %vol, 0 510ad5a84c8SPhilip Reames br i1 %unknown, label %loop, label %exit 511ad5a84c8SPhilip Reames 512ad5a84c8SPhilip Reamesexit: 513ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 514ad5a84c8SPhilip Reames ret i32 %result 515ad5a84c8SPhilip Reames} 516ad5a84c8SPhilip Reames 517ad5a84c8SPhilip Reames 518ad5a84c8SPhilip Reamesdefine i32 @provably_taken(i32* %array, i1 %cond_0) { 519ad5a84c8SPhilip Reames; CHECK-LABEL: @provably_taken( 520ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 521ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 522ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 false 523ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]] 524ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]] 525ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 526ad5a84c8SPhilip Reames; CHECK: deopt: 527ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 528ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 529ad5a84c8SPhilip Reames; CHECK: loop.preheader: 530ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 531ad5a84c8SPhilip Reames; CHECK: loop: 532ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 533ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 534ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 535ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 198 536ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 537ad5a84c8SPhilip Reames; CHECK: deopt2: 538ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 539ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 540ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 541ad5a84c8SPhilip Reames; CHECK: guarded: 542ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 543ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 544ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 545*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 546ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 547ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 548ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200 549ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 550ad5a84c8SPhilip Reames; CHECK: exit: 551ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 552ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 553ad5a84c8SPhilip Reames; 554ad5a84c8SPhilip Reamesentry: 555ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 556ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 557ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 558ad5a84c8SPhilip Reames 559ad5a84c8SPhilip Reamesdeopt: 560ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 561ad5a84c8SPhilip Reames ret i32 %deoptret 562ad5a84c8SPhilip Reames 563ad5a84c8SPhilip Reamesloop.preheader: 564ad5a84c8SPhilip Reames br label %loop 565ad5a84c8SPhilip Reames 566ad5a84c8SPhilip Reamesloop: 567ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 568ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 569ad5a84c8SPhilip Reames call void @unknown() 570ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, 198 571ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 572ad5a84c8SPhilip Reames 573ad5a84c8SPhilip Reamesdeopt2: 574ad5a84c8SPhilip Reames call void @unknown() 575ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 576ad5a84c8SPhilip Reames ret i32 %deoptret2 577ad5a84c8SPhilip Reames 578ad5a84c8SPhilip Reamesguarded: 579ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 580ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 581ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 582ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 583ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 584ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 585ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, 200 586ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 587ad5a84c8SPhilip Reames 588ad5a84c8SPhilip Reamesexit: 589ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 590ad5a84c8SPhilip Reames ret i32 %result 591ad5a84c8SPhilip Reames} 592ad5a84c8SPhilip Reames 593ad5a84c8SPhilip Reamesdefine i32 @provably_not_taken(i32* %array, i1 %cond_0) { 594ad5a84c8SPhilip Reames; CHECK-LABEL: @provably_not_taken( 595ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 596ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 597ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 true 598ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]] 599ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]] 600ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 601ad5a84c8SPhilip Reames; CHECK: deopt: 602ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 603ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 604ad5a84c8SPhilip Reames; CHECK: loop.preheader: 605ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 606ad5a84c8SPhilip Reames; CHECK: loop: 607ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 608ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 609ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 610ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 205 611ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 612ad5a84c8SPhilip Reames; CHECK: deopt2: 613ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 614ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 615ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 616ad5a84c8SPhilip Reames; CHECK: guarded: 617ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 618ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 619ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 620*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 621ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 622ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 623ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200 624ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 625ad5a84c8SPhilip Reames; CHECK: exit: 626ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 627ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 628ad5a84c8SPhilip Reames; 629ad5a84c8SPhilip Reamesentry: 630ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 631ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 632ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 633ad5a84c8SPhilip Reames 634ad5a84c8SPhilip Reamesdeopt: 635ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 636ad5a84c8SPhilip Reames ret i32 %deoptret 637ad5a84c8SPhilip Reames 638ad5a84c8SPhilip Reamesloop.preheader: 639ad5a84c8SPhilip Reames br label %loop 640ad5a84c8SPhilip Reames 641ad5a84c8SPhilip Reamesloop: 642ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 643ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 644ad5a84c8SPhilip Reames call void @unknown() 645ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, 205 646ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 647ad5a84c8SPhilip Reames 648ad5a84c8SPhilip Reamesdeopt2: 649ad5a84c8SPhilip Reames call void @unknown() 650ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 651ad5a84c8SPhilip Reames ret i32 %deoptret2 652ad5a84c8SPhilip Reames 653ad5a84c8SPhilip Reamesguarded: 654ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 655ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 656ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 657ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 658ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 659ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 660ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, 200 661ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 662ad5a84c8SPhilip Reames 663ad5a84c8SPhilip Reamesexit: 664ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 665ad5a84c8SPhilip Reames ret i32 %result 666ad5a84c8SPhilip Reames} 667ad5a84c8SPhilip Reames 668ad5a84c8SPhilip Reames 669f3eb5deeSPhilip Reames;; Unswitch likes to produce some ugly exit blocks without simplifications 670f3eb5deeSPhilip Reames;; being applied. Make sure we can handle that form. 671f3eb5deeSPhilip Reamesdefine i32 @unswitch_exit_form(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 672f3eb5deeSPhilip Reames; CHECK-LABEL: @unswitch_exit_form( 673f3eb5deeSPhilip Reames; CHECK-NEXT: entry: 674f3eb5deeSPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 675*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 676*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 677*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 678*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 679*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 680*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 681*b46c085dSRoman Lebedev; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 682f3eb5deeSPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 683f3eb5deeSPhilip Reames; CHECK: deopt.loopexit: 684f3eb5deeSPhilip Reames; CHECK-NEXT: br label [[DEOPT]] 685f3eb5deeSPhilip Reames; CHECK: deopt: 686f3eb5deeSPhilip Reames; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[DEOPT_LOOPEXIT:%.*]] ] 687f3eb5deeSPhilip Reames; CHECK-NEXT: call void @unknown() 688f3eb5deeSPhilip Reames; CHECK-NEXT: br label [[ACTUAL_DEOPT:%.*]] 689f3eb5deeSPhilip Reames; CHECK: actual_deopt: 690f3eb5deeSPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ] 691f3eb5deeSPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 692f3eb5deeSPhilip Reames; CHECK: loop.preheader: 693f3eb5deeSPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 694f3eb5deeSPhilip Reames; CHECK: loop: 695f3eb5deeSPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 696f3eb5deeSPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 697f3eb5deeSPhilip Reames; CHECK-NEXT: call void @unknown() 698f3eb5deeSPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 699f3eb5deeSPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof !0 700f3eb5deeSPhilip Reames; CHECK: guarded: 701f3eb5deeSPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 702f3eb5deeSPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 703f3eb5deeSPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 704*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 705f3eb5deeSPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 706f3eb5deeSPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 707f3eb5deeSPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 708f3eb5deeSPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 709f3eb5deeSPhilip Reames; CHECK: exit: 710f3eb5deeSPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 711f3eb5deeSPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 712f3eb5deeSPhilip Reames; 713f3eb5deeSPhilip Reamesentry: 714f3eb5deeSPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 715f3eb5deeSPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 716f3eb5deeSPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 717ad5a84c8SPhilip Reames 718f3eb5deeSPhilip Reamesdeopt: 719f3eb5deeSPhilip Reames ;; This is written to look like an unsimplified loop exit after unswitch 720f3eb5deeSPhilip Reames ;; (i.e. phis, merge, and branch to actual block) 721f3eb5deeSPhilip Reames %phi = phi i32 [0, %entry], [1, %loop] 722f3eb5deeSPhilip Reames call void @unknown() ;; it's okay to skip possible throws 723f3eb5deeSPhilip Reames br label %actual_deopt 724ad5a84c8SPhilip Reames 725f3eb5deeSPhilip Reamesactual_deopt: 726f3eb5deeSPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ] 727f3eb5deeSPhilip Reames ret i32 %deoptret 728ad5a84c8SPhilip Reames 729f3eb5deeSPhilip Reamesloop.preheader: 730f3eb5deeSPhilip Reames br label %loop 731ad5a84c8SPhilip Reames 732f3eb5deeSPhilip Reamesloop: 733f3eb5deeSPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 734f3eb5deeSPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 735f3eb5deeSPhilip Reames call void @unknown() 736f3eb5deeSPhilip Reames %within.bounds = icmp ult i32 %i, %length 737f3eb5deeSPhilip Reames br i1 %within.bounds, label %guarded, label %deopt, !prof !0 738ad5a84c8SPhilip Reames 739f3eb5deeSPhilip Reamesguarded: 740f3eb5deeSPhilip Reames %i.i64 = zext i32 %i to i64 741f3eb5deeSPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 742f3eb5deeSPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 743f3eb5deeSPhilip Reames store i32 0, i32* %array.i.ptr 744f3eb5deeSPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 745f3eb5deeSPhilip Reames %i.next = add nuw i32 %i, 1 746f3eb5deeSPhilip Reames %continue = icmp ult i32 %i.next, %n 747f3eb5deeSPhilip Reames br i1 %continue, label %loop, label %exit 748f3eb5deeSPhilip Reames 749f3eb5deeSPhilip Reamesexit: 750f3eb5deeSPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 751f3eb5deeSPhilip Reames ret i32 %result 752f3eb5deeSPhilip Reames} 753ad5a84c8SPhilip Reames 754aaea2480SPhilip Reamesdefine i32 @swapped_wb(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 755aaea2480SPhilip Reames; CHECK-LABEL: @swapped_wb( 756aaea2480SPhilip Reames; CHECK-NEXT: entry: 757aaea2480SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 758*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 759*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 760*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 761*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 762*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 763*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 764*b46c085dSRoman Lebedev; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] 765aaea2480SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 766aaea2480SPhilip Reames; CHECK: deopt: 767aaea2480SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 768aaea2480SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 769aaea2480SPhilip Reames; CHECK: loop.preheader: 770aaea2480SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 771aaea2480SPhilip Reames; CHECK: loop: 772aaea2480SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 773aaea2480SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 774aaea2480SPhilip Reames; CHECK-NEXT: call void @unknown() 775aaea2480SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 776aaea2480SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 777aaea2480SPhilip Reames; CHECK: deopt2: 778aaea2480SPhilip Reames; CHECK-NEXT: call void @unknown() 779aaea2480SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 780aaea2480SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 781aaea2480SPhilip Reames; CHECK: guarded: 782aaea2480SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 783aaea2480SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 784aaea2480SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 785*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 786aaea2480SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 787aaea2480SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 788aaea2480SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 789aaea2480SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 790aaea2480SPhilip Reames; CHECK: exit: 791aaea2480SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 792aaea2480SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 793aaea2480SPhilip Reames; 794aaea2480SPhilip Reamesentry: 795aaea2480SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 796aaea2480SPhilip Reames %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0 797aaea2480SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 798aaea2480SPhilip Reames 799aaea2480SPhilip Reamesdeopt: 800aaea2480SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 801aaea2480SPhilip Reames ret i32 %deoptret 802aaea2480SPhilip Reames 803aaea2480SPhilip Reamesloop.preheader: 804aaea2480SPhilip Reames br label %loop 805aaea2480SPhilip Reames 806aaea2480SPhilip Reamesloop: 807aaea2480SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 808aaea2480SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 809aaea2480SPhilip Reames call void @unknown() 810aaea2480SPhilip Reames %within.bounds = icmp ult i32 %i, %length 811aaea2480SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 812aaea2480SPhilip Reames 813aaea2480SPhilip Reamesdeopt2: 814aaea2480SPhilip Reames call void @unknown() 815aaea2480SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 816aaea2480SPhilip Reames ret i32 %deoptret2 817aaea2480SPhilip Reames 818aaea2480SPhilip Reamesguarded: 819aaea2480SPhilip Reames %i.i64 = zext i32 %i to i64 820aaea2480SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 821aaea2480SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 822aaea2480SPhilip Reames store i32 0, i32* %array.i.ptr 823aaea2480SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 824aaea2480SPhilip Reames %i.next = add nuw i32 %i, 1 825aaea2480SPhilip Reames %continue = icmp ult i32 %i.next, %n 826aaea2480SPhilip Reames br i1 %continue, label %loop, label %exit 827aaea2480SPhilip Reames 828aaea2480SPhilip Reamesexit: 829aaea2480SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 830aaea2480SPhilip Reames ret i32 %result 831aaea2480SPhilip Reames} 832aaea2480SPhilip Reames 833aaea2480SPhilip Reamesdefine i32 @trivial_wb(i32* %array, i32 %length, i32 %n) { 834aaea2480SPhilip Reames; CHECK-LABEL: @trivial_wb( 835aaea2480SPhilip Reames; CHECK-NEXT: entry: 836*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 837*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 838*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 839*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 840*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 841aaea2480SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 842*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] 843*b46c085dSRoman Lebedev; CHECK-NEXT: br i1 [[TMP3]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 844aaea2480SPhilip Reames; CHECK: deopt: 845aaea2480SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 846aaea2480SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 847aaea2480SPhilip Reames; CHECK: loop.preheader: 848aaea2480SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 849aaea2480SPhilip Reames; CHECK: loop: 850aaea2480SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 851aaea2480SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 852aaea2480SPhilip Reames; CHECK-NEXT: call void @unknown() 853aaea2480SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 854aaea2480SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 855aaea2480SPhilip Reames; CHECK: deopt2: 856aaea2480SPhilip Reames; CHECK-NEXT: call void @unknown() 857aaea2480SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 858aaea2480SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 859aaea2480SPhilip Reames; CHECK: guarded: 860aaea2480SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 861aaea2480SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 862aaea2480SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 863*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 864aaea2480SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 865aaea2480SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 866aaea2480SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 867aaea2480SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 868aaea2480SPhilip Reames; CHECK: exit: 869aaea2480SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 870aaea2480SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 871aaea2480SPhilip Reames; 872aaea2480SPhilip Reamesentry: 873aaea2480SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 874aaea2480SPhilip Reames br i1 %widenable_cond, label %loop.preheader, label %deopt, !prof !0 875aaea2480SPhilip Reames 876aaea2480SPhilip Reamesdeopt: 877aaea2480SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 878aaea2480SPhilip Reames ret i32 %deoptret 879aaea2480SPhilip Reames 880aaea2480SPhilip Reamesloop.preheader: 881aaea2480SPhilip Reames br label %loop 882aaea2480SPhilip Reames 883aaea2480SPhilip Reamesloop: 884aaea2480SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 885aaea2480SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 886aaea2480SPhilip Reames call void @unknown() 887aaea2480SPhilip Reames %within.bounds = icmp ult i32 %i, %length 888aaea2480SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 889aaea2480SPhilip Reames 890aaea2480SPhilip Reamesdeopt2: 891aaea2480SPhilip Reames call void @unknown() 892aaea2480SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 893aaea2480SPhilip Reames ret i32 %deoptret2 894aaea2480SPhilip Reames 895aaea2480SPhilip Reamesguarded: 896aaea2480SPhilip Reames %i.i64 = zext i32 %i to i64 897aaea2480SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 898aaea2480SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 899aaea2480SPhilip Reames store i32 0, i32* %array.i.ptr 900aaea2480SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 901aaea2480SPhilip Reames %i.next = add nuw i32 %i, 1 902aaea2480SPhilip Reames %continue = icmp ult i32 %i.next, %n 903aaea2480SPhilip Reames br i1 %continue, label %loop, label %exit 904aaea2480SPhilip Reames 905aaea2480SPhilip Reamesexit: 906aaea2480SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 907aaea2480SPhilip Reames ret i32 %result 908aaea2480SPhilip Reames} 909aaea2480SPhilip Reames 910ad5a84c8SPhilip Reames; TODO: Non-latch exits can still be predicated 911ad5a84c8SPhilip Reames; This is currently prevented by an overly restrictive profitability check. 912ad5a84c8SPhilip Reamesdefine i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) { 913ad5a84c8SPhilip Reames; CHECK-LABEL: @todo_unconditional_latch( 914ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 915ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 916ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 917ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 918ad5a84c8SPhilip Reames; CHECK: deopt: 919ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 920ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 921ad5a84c8SPhilip Reames; CHECK: loop.preheader: 922ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 923ad5a84c8SPhilip Reames; CHECK: loop: 924ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 925ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 926ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 927ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 928ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 929ad5a84c8SPhilip Reames; CHECK: deopt2: 930ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 931ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 932ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 933ad5a84c8SPhilip Reames; CHECK: guarded: 934ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 935ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 936ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 937*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 938ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 939ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 940ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP]] 941ad5a84c8SPhilip Reames; 942ad5a84c8SPhilip Reamesentry: 943ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 944ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 945ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 946ad5a84c8SPhilip Reames 947ad5a84c8SPhilip Reamesdeopt: 948ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 949ad5a84c8SPhilip Reames ret i32 %deoptret 950ad5a84c8SPhilip Reames 951ad5a84c8SPhilip Reamesloop.preheader: 952ad5a84c8SPhilip Reames br label %loop 953ad5a84c8SPhilip Reames 954ad5a84c8SPhilip Reamesloop: 955ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 956ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 957ad5a84c8SPhilip Reames call void @unknown() 958ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 959ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 960ad5a84c8SPhilip Reames 961ad5a84c8SPhilip Reamesdeopt2: 962ad5a84c8SPhilip Reames call void @unknown() 963ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 964ad5a84c8SPhilip Reames ret i32 %deoptret2 965ad5a84c8SPhilip Reames 966ad5a84c8SPhilip Reamesguarded: 967ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 968ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 969ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 970ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 971ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 972ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 973ad5a84c8SPhilip Reames br label %loop 974ad5a84c8SPhilip Reames} 975ad5a84c8SPhilip Reames 976ad5a84c8SPhilip Reames 977dfb7a909SPhilip Reames; If we have a stray widenable branch in the loop, we should still be able to 978dfb7a909SPhilip Reames; run. This can happen when unswitching's cost model avoids unswitching some 979dfb7a909SPhilip Reames; branches. 980dfb7a909SPhilip Reamesdefine i32 @wb_in_loop(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 981dfb7a909SPhilip Reames; CHECK-LABEL: @wb_in_loop( 982dfb7a909SPhilip Reames; CHECK-NEXT: entry: 983dfb7a909SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 984dfb7a909SPhilip Reames; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() 985*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 986*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 987*b46c085dSRoman Lebedev; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 988*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 989*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 990*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 991*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 992*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]] 993*b46c085dSRoman Lebedev; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]] 994*b46c085dSRoman Lebedev; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]] 995dfb7a909SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 996dfb7a909SPhilip Reames; CHECK: deopt: 997dfb7a909SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 998dfb7a909SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 999dfb7a909SPhilip Reames; CHECK: loop.preheader: 1000dfb7a909SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 1001dfb7a909SPhilip Reames; CHECK: loop: 1002dfb7a909SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1003dfb7a909SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 1004dfb7a909SPhilip Reames; CHECK-NEXT: call void @unknown() 1005dfb7a909SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 1006dfb7a909SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0 1007dfb7a909SPhilip Reames; CHECK: deopt2: 1008dfb7a909SPhilip Reames; CHECK-NEXT: call void @unknown() 1009dfb7a909SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1010dfb7a909SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 1011dfb7a909SPhilip Reames; CHECK: guarded: 1012dfb7a909SPhilip Reames; CHECK-NEXT: call void @unknown() 1013dfb7a909SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 1014dfb7a909SPhilip Reames; CHECK-NEXT: [[WB_COND:%.*]] = and i1 [[WITHIN_BOUNDS2]], true 1015dfb7a909SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 1016dfb7a909SPhilip Reames; CHECK: deopt3: 1017dfb7a909SPhilip Reames; CHECK-NEXT: call void @unknown() 1018dfb7a909SPhilip Reames; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1019dfb7a909SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET3]] 1020dfb7a909SPhilip Reames; CHECK: guarded2: 1021dfb7a909SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1022dfb7a909SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1023dfb7a909SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1024*b46c085dSRoman Lebedev; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 1025dfb7a909SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1026dfb7a909SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1027dfb7a909SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1028dfb7a909SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 1029dfb7a909SPhilip Reames; CHECK: exit: 1030dfb7a909SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 1031dfb7a909SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 1032dfb7a909SPhilip Reames; 1033dfb7a909SPhilip Reamesentry: 1034dfb7a909SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1035dfb7a909SPhilip Reames %wc2 = call i1 @llvm.experimental.widenable.condition() 1036dfb7a909SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 1037dfb7a909SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 1038dfb7a909SPhilip Reames 1039dfb7a909SPhilip Reamesdeopt: 1040dfb7a909SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1041dfb7a909SPhilip Reames ret i32 %deoptret 1042dfb7a909SPhilip Reames 1043dfb7a909SPhilip Reamesloop.preheader: 1044dfb7a909SPhilip Reames br label %loop 1045dfb7a909SPhilip Reames 1046dfb7a909SPhilip Reamesloop: 1047dfb7a909SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 1048dfb7a909SPhilip Reames %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 1049dfb7a909SPhilip Reames call void @unknown() 1050dfb7a909SPhilip Reames %within.bounds = icmp ult i32 %i, %length 1051dfb7a909SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 1052dfb7a909SPhilip Reames 1053dfb7a909SPhilip Reamesdeopt2: 1054dfb7a909SPhilip Reames call void @unknown() 1055dfb7a909SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1056dfb7a909SPhilip Reames ret i32 %deoptret2 1057dfb7a909SPhilip Reames 1058dfb7a909SPhilip Reamesguarded: 1059dfb7a909SPhilip Reames call void @unknown() 1060dfb7a909SPhilip Reames %within.bounds2 = icmp ult i32 %i, %length 1061dfb7a909SPhilip Reames %wb_cond = and i1 %within.bounds2, %wc2 1062dfb7a909SPhilip Reames br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0 1063dfb7a909SPhilip Reames 1064dfb7a909SPhilip Reamesdeopt3: 1065dfb7a909SPhilip Reames call void @unknown() 1066dfb7a909SPhilip Reames %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1067dfb7a909SPhilip Reames ret i32 %deoptret3 1068dfb7a909SPhilip Reames 1069dfb7a909SPhilip Reamesguarded2: 1070dfb7a909SPhilip Reames %i.i64 = zext i32 %i to i64 1071dfb7a909SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1072dfb7a909SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 1073dfb7a909SPhilip Reames store i32 0, i32* %array.i.ptr 1074dfb7a909SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 1075dfb7a909SPhilip Reames %i.next = add nuw i32 %i, 1 1076dfb7a909SPhilip Reames %continue = icmp ult i32 %i.next, %n 1077dfb7a909SPhilip Reames br i1 %continue, label %loop, label %exit 1078dfb7a909SPhilip Reames 1079dfb7a909SPhilip Reamesexit: 1080dfb7a909SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded2 ] 1081dfb7a909SPhilip Reames ret i32 %result 1082dfb7a909SPhilip Reames} 1083dfb7a909SPhilip Reames 1084dfb7a909SPhilip Reames 1085dfb7a909SPhilip Reames 1086ad5a84c8SPhilip Reamesdeclare void @unknown() 1087ad5a84c8SPhilip Reames 1088ad5a84c8SPhilip Reamesdeclare i1 @llvm.experimental.widenable.condition() 1089ad5a84c8SPhilip Reamesdeclare i32 @llvm.experimental.deoptimize.i32(...) 1090ad5a84c8SPhilip Reames 1091ad5a84c8SPhilip Reames!0 = !{!"branch_weights", i32 1048576, i32 1} 1092ad5a84c8SPhilip Reames!1 = !{i32 1, i32 -2147483648} 1093ad5a84c8SPhilip Reames!2 = !{i32 0, i32 50} 1094