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 678*f3eb5deeSPhilip Reames;; Unswitch likes to produce some ugly exit blocks without simplifications 679*f3eb5deeSPhilip Reames;; being applied. Make sure we can handle that form. 680*f3eb5deeSPhilip Reamesdefine i32 @unswitch_exit_form(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 681*f3eb5deeSPhilip Reames; CHECK-LABEL: @unswitch_exit_form( 682*f3eb5deeSPhilip Reames; CHECK-NEXT: entry: 683*f3eb5deeSPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 684*f3eb5deeSPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1 685*f3eb5deeSPhilip Reames; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1 686*f3eb5deeSPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[UMAX]], -1 687*f3eb5deeSPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]] 688*f3eb5deeSPhilip Reames; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]] 689*f3eb5deeSPhilip Reames; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 690*f3eb5deeSPhilip Reames; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] 691*f3eb5deeSPhilip Reames; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]] 692*f3eb5deeSPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]] 693*f3eb5deeSPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 694*f3eb5deeSPhilip Reames; CHECK: deopt.loopexit: 695*f3eb5deeSPhilip Reames; CHECK-NEXT: br label [[DEOPT]] 696*f3eb5deeSPhilip Reames; CHECK: deopt: 697*f3eb5deeSPhilip Reames; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[DEOPT_LOOPEXIT:%.*]] ] 698*f3eb5deeSPhilip Reames; CHECK-NEXT: call void @unknown() 699*f3eb5deeSPhilip Reames; CHECK-NEXT: br label [[ACTUAL_DEOPT:%.*]] 700*f3eb5deeSPhilip Reames; CHECK: actual_deopt: 701*f3eb5deeSPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ] 702*f3eb5deeSPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 703*f3eb5deeSPhilip Reames; CHECK: loop.preheader: 704*f3eb5deeSPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 705*f3eb5deeSPhilip Reames; CHECK: loop: 706*f3eb5deeSPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 707*f3eb5deeSPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 708*f3eb5deeSPhilip Reames; CHECK-NEXT: call void @unknown() 709*f3eb5deeSPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 710*f3eb5deeSPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof !0 711*f3eb5deeSPhilip Reames; CHECK: guarded: 712*f3eb5deeSPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 713*f3eb5deeSPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 714*f3eb5deeSPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 715*f3eb5deeSPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 716*f3eb5deeSPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 717*f3eb5deeSPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 718*f3eb5deeSPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 719*f3eb5deeSPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 720*f3eb5deeSPhilip Reames; CHECK: exit: 721*f3eb5deeSPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 722*f3eb5deeSPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 723*f3eb5deeSPhilip Reames; 724*f3eb5deeSPhilip Reamesentry: 725*f3eb5deeSPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 726*f3eb5deeSPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 727*f3eb5deeSPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 728ad5a84c8SPhilip Reames 729*f3eb5deeSPhilip Reamesdeopt: 730*f3eb5deeSPhilip Reames ;; This is written to look like an unsimplified loop exit after unswitch 731*f3eb5deeSPhilip Reames ;; (i.e. phis, merge, and branch to actual block) 732*f3eb5deeSPhilip Reames %phi = phi i32 [0, %entry], [1, %loop] 733*f3eb5deeSPhilip Reames call void @unknown() ;; it's okay to skip possible throws 734*f3eb5deeSPhilip Reames br label %actual_deopt 735ad5a84c8SPhilip Reames 736*f3eb5deeSPhilip Reamesactual_deopt: 737*f3eb5deeSPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ] 738*f3eb5deeSPhilip Reames ret i32 %deoptret 739ad5a84c8SPhilip Reames 740*f3eb5deeSPhilip Reamesloop.preheader: 741*f3eb5deeSPhilip Reames br label %loop 742ad5a84c8SPhilip Reames 743*f3eb5deeSPhilip Reamesloop: 744*f3eb5deeSPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 745*f3eb5deeSPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 746*f3eb5deeSPhilip Reames call void @unknown() 747*f3eb5deeSPhilip Reames %within.bounds = icmp ult i32 %i, %length 748*f3eb5deeSPhilip Reames br i1 %within.bounds, label %guarded, label %deopt, !prof !0 749ad5a84c8SPhilip Reames 750*f3eb5deeSPhilip Reamesguarded: 751*f3eb5deeSPhilip Reames %i.i64 = zext i32 %i to i64 752*f3eb5deeSPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 753*f3eb5deeSPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 754*f3eb5deeSPhilip Reames store i32 0, i32* %array.i.ptr 755*f3eb5deeSPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 756*f3eb5deeSPhilip Reames %i.next = add nuw i32 %i, 1 757*f3eb5deeSPhilip Reames %continue = icmp ult i32 %i.next, %n 758*f3eb5deeSPhilip Reames br i1 %continue, label %loop, label %exit 759*f3eb5deeSPhilip Reames 760*f3eb5deeSPhilip Reamesexit: 761*f3eb5deeSPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 762*f3eb5deeSPhilip Reames ret i32 %result 763*f3eb5deeSPhilip Reames} 764ad5a84c8SPhilip Reames 765ad5a84c8SPhilip Reames; TODO: Non-latch exits can still be predicated 766ad5a84c8SPhilip Reames; This is currently prevented by an overly restrictive profitability check. 767ad5a84c8SPhilip Reamesdefine i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) { 768ad5a84c8SPhilip Reames; CHECK-LABEL: @todo_unconditional_latch( 769ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 770ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 771ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 772ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 773ad5a84c8SPhilip Reames; CHECK: deopt: 774ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 775ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 776ad5a84c8SPhilip Reames; CHECK: loop.preheader: 777ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 778ad5a84c8SPhilip Reames; CHECK: loop: 779ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 780ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 781ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 782ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 783ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 784ad5a84c8SPhilip Reames; CHECK: deopt2: 785ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 786ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 787ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 788ad5a84c8SPhilip Reames; CHECK: guarded: 789ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 790ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 791ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 792ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 793ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 794ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 795ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP]] 796ad5a84c8SPhilip Reames; 797ad5a84c8SPhilip Reamesentry: 798ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 799ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 800ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 801ad5a84c8SPhilip Reames 802ad5a84c8SPhilip Reamesdeopt: 803ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 804ad5a84c8SPhilip Reames ret i32 %deoptret 805ad5a84c8SPhilip Reames 806ad5a84c8SPhilip Reamesloop.preheader: 807ad5a84c8SPhilip Reames br label %loop 808ad5a84c8SPhilip Reames 809ad5a84c8SPhilip Reamesloop: 810ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 811ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 812ad5a84c8SPhilip Reames call void @unknown() 813ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 814ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 815ad5a84c8SPhilip Reames 816ad5a84c8SPhilip Reamesdeopt2: 817ad5a84c8SPhilip Reames call void @unknown() 818ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 819ad5a84c8SPhilip Reames ret i32 %deoptret2 820ad5a84c8SPhilip Reames 821ad5a84c8SPhilip Reamesguarded: 822ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 823ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 824ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 825ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 826ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 827ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 828ad5a84c8SPhilip Reames br label %loop 829ad5a84c8SPhilip Reames} 830ad5a84c8SPhilip Reames 831ad5a84c8SPhilip Reames 832ad5a84c8SPhilip Reamesdeclare void @unknown() 833ad5a84c8SPhilip Reames 834ad5a84c8SPhilip Reamesdeclare i1 @llvm.experimental.widenable.condition() 835ad5a84c8SPhilip Reamesdeclare i32 @llvm.experimental.deoptimize.i32(...) 836ad5a84c8SPhilip Reames 837ad5a84c8SPhilip Reames!0 = !{!"branch_weights", i32 1048576, i32 1} 838ad5a84c8SPhilip Reames!1 = !{i32 1, i32 -2147483648} 839ad5a84c8SPhilip Reames!2 = !{i32 0, i32 50} 840