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