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