1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=indvars -S -indvars-predicate-loops=0 < %s | FileCheck %s 3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" 5 6define i32 @remove_loop(i32 %size) { 7; CHECK-LABEL: @remove_loop( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[SIZE:%.*]], 31 10; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SIZE]], i32 31) 11; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[UMIN]] 12; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], 5 13; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i32 [[TMP2]], 5 14; CHECK-NEXT: br label [[WHILE_COND:%.*]] 15; CHECK: while.cond: 16; CHECK-NEXT: [[SIZE_ADDR_0:%.*]] = phi i32 [ [[SIZE]], [[ENTRY:%.*]] ], [ [[SUB:%.*]], [[WHILE_COND]] ] 17; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[SIZE_ADDR_0]], 31 18; CHECK-NEXT: [[SUB]] = add i32 [[SIZE_ADDR_0]], -32 19; CHECK-NEXT: br i1 [[CMP]], label [[WHILE_COND]], label [[WHILE_END:%.*]] 20; CHECK: while.end: 21; CHECK-NEXT: [[TMP4:%.*]] = sub i32 [[SIZE]], [[TMP3]] 22; CHECK-NEXT: ret i32 [[TMP4]] 23; 24entry: 25 br label %while.cond 26 27while.cond: ; preds = %while.cond, %entry 28 %size.addr.0 = phi i32 [ %size, %entry ], [ %sub, %while.cond ] 29 %cmp = icmp ugt i32 %size.addr.0, 31 30 %sub = add i32 %size.addr.0, -32 31 br i1 %cmp, label %while.cond, label %while.end 32 33while.end: ; preds = %while.cond 34 %size.lcssa = phi i32 [ %size.addr.0, %while.cond ] 35 ret i32 %size.lcssa 36} 37 38define i32 @used_loop(i32 %size) minsize { 39; CHECK-LABEL: @used_loop( 40; CHECK-NEXT: entry: 41; CHECK-NEXT: br label [[WHILE_COND:%.*]] 42; CHECK: while.cond: 43; CHECK-NEXT: [[SIZE_ADDR_0:%.*]] = phi i32 [ [[SIZE:%.*]], [[ENTRY:%.*]] ], [ [[SUB:%.*]], [[WHILE_COND]] ] 44; CHECK-NEXT: tail call void @call() 45; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[SIZE_ADDR_0]], 31 46; CHECK-NEXT: [[SUB]] = add i32 [[SIZE_ADDR_0]], -32 47; CHECK-NEXT: br i1 [[CMP]], label [[WHILE_COND]], label [[WHILE_END:%.*]] 48; CHECK: while.end: 49; CHECK-NEXT: [[SIZE_LCSSA:%.*]] = phi i32 [ [[SIZE_ADDR_0]], [[WHILE_COND]] ] 50; CHECK-NEXT: ret i32 [[SIZE_LCSSA]] 51; 52entry: 53 br label %while.cond 54 55while.cond: ; preds = %while.cond, %entry 56 %size.addr.0 = phi i32 [ %size, %entry ], [ %sub, %while.cond ] 57 tail call void @call() 58 %cmp = icmp ugt i32 %size.addr.0, 31 59 %sub = add i32 %size.addr.0, -32 60 br i1 %cmp, label %while.cond, label %while.end 61 62while.end: ; preds = %while.cond 63 %size.lcssa = phi i32 [ %size.addr.0, %while.cond ] 64 ret i32 %size.lcssa 65} 66 67 68define i32 @test_signed_while(i32 %S) { 69; CHECK-LABEL: @test_signed_while( 70; CHECK-NEXT: entry: 71; CHECK-NEXT: br label [[WHILE_COND:%.*]] 72; CHECK: while.cond: 73; CHECK-NEXT: [[S_ADDR_0:%.*]] = phi i32 [ [[S:%.*]], [[ENTRY:%.*]] ], [ [[SUB:%.*]], [[WHILE_BODY:%.*]] ] 74; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S_ADDR_0]], 31 75; CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY]], label [[WHILE_END:%.*]] 76; CHECK: while.body: 77; CHECK-NEXT: [[SUB]] = add nsw i32 [[S_ADDR_0]], -32 78; CHECK-NEXT: tail call void @call() 79; CHECK-NEXT: br label [[WHILE_COND]] 80; CHECK: while.end: 81; CHECK-NEXT: [[S_ADDR_0_LCSSA:%.*]] = phi i32 [ [[S_ADDR_0]], [[WHILE_COND]] ] 82; CHECK-NEXT: ret i32 [[S_ADDR_0_LCSSA]] 83; 84entry: 85 br label %while.cond 86 87while.cond: ; preds = %while.body, %entry 88 %S.addr.0 = phi i32 [ %S, %entry ], [ %sub, %while.body ] 89 %cmp = icmp sgt i32 %S.addr.0, 31 90 br i1 %cmp, label %while.body, label %while.end 91 92while.body: ; preds = %while.cond 93 %sub = add nsw i32 %S.addr.0, -32 94 tail call void @call() 95 br label %while.cond 96 97while.end: ; preds = %while.cond 98 %S.addr.0.lcssa = phi i32 [ %S.addr.0, %while.cond ] 99 ret i32 %S.addr.0.lcssa 100} 101 102define i32 @test_signed_do(i32 %S) { 103; CHECK-LABEL: @test_signed_do( 104; CHECK-NEXT: entry: 105; CHECK-NEXT: br label [[DO_BODY:%.*]] 106; CHECK: do.body: 107; CHECK-NEXT: [[S_ADDR_0:%.*]] = phi i32 [ [[S:%.*]], [[ENTRY:%.*]] ], [ [[SUB:%.*]], [[DO_BODY]] ] 108; CHECK-NEXT: [[SUB]] = add nsw i32 [[S_ADDR_0]], -16 109; CHECK-NEXT: tail call void @call() 110; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[SUB]], 15 111; CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]] 112; CHECK: do.end: 113; CHECK-NEXT: [[SUB_LCSSA:%.*]] = phi i32 [ [[SUB]], [[DO_BODY]] ] 114; CHECK-NEXT: ret i32 [[SUB_LCSSA]] 115; 116entry: 117 br label %do.body 118 119do.body: ; preds = %do.body, %entry 120 %S.addr.0 = phi i32 [ %S, %entry ], [ %sub, %do.body ] 121 %sub = add nsw i32 %S.addr.0, -16 122 tail call void @call() 123 %cmp = icmp sgt i32 %sub, 15 124 br i1 %cmp, label %do.body, label %do.end 125 126do.end: ; preds = %do.body 127 %sub.lcssa = phi i32 [ %sub, %do.body ] 128 ret i32 %sub.lcssa 129} 130 131define i32 @test_unsigned_while(i32 %S) { 132; CHECK-LABEL: @test_unsigned_while( 133; CHECK-NEXT: entry: 134; CHECK-NEXT: br label [[WHILE_COND:%.*]] 135; CHECK: while.cond: 136; CHECK-NEXT: [[S_ADDR_0:%.*]] = phi i32 [ [[S:%.*]], [[ENTRY:%.*]] ], [ [[SUB:%.*]], [[WHILE_BODY:%.*]] ] 137; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[S_ADDR_0]], 15 138; CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY]], label [[WHILE_END:%.*]] 139; CHECK: while.body: 140; CHECK-NEXT: [[SUB]] = add i32 [[S_ADDR_0]], -16 141; CHECK-NEXT: tail call void @call() 142; CHECK-NEXT: br label [[WHILE_COND]] 143; CHECK: while.end: 144; CHECK-NEXT: [[S_ADDR_0_LCSSA:%.*]] = phi i32 [ [[S_ADDR_0]], [[WHILE_COND]] ] 145; CHECK-NEXT: ret i32 [[S_ADDR_0_LCSSA]] 146; 147entry: 148 br label %while.cond 149 150while.cond: ; preds = %while.body, %entry 151 %S.addr.0 = phi i32 [ %S, %entry ], [ %sub, %while.body ] 152 %cmp = icmp ugt i32 %S.addr.0, 15 153 br i1 %cmp, label %while.body, label %while.end 154 155while.body: ; preds = %while.cond 156 %sub = add i32 %S.addr.0, -16 157 tail call void @call() 158 br label %while.cond 159 160while.end: ; preds = %while.cond 161 %S.addr.0.lcssa = phi i32 [ %S.addr.0, %while.cond ] 162 ret i32 %S.addr.0.lcssa 163} 164 165define i32 @test_unsigned_do(i32 %S) { 166; CHECK-LABEL: @test_unsigned_do( 167; CHECK-NEXT: entry: 168; CHECK-NEXT: br label [[DO_BODY:%.*]] 169; CHECK: do.body: 170; CHECK-NEXT: [[S_ADDR_0:%.*]] = phi i32 [ [[S:%.*]], [[ENTRY:%.*]] ], [ [[SUB:%.*]], [[DO_BODY]] ] 171; CHECK-NEXT: [[SUB]] = add i32 [[S_ADDR_0]], -16 172; CHECK-NEXT: tail call void @call() 173; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[SUB]], 15 174; CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]] 175; CHECK: do.end: 176; CHECK-NEXT: [[SUB_LCSSA:%.*]] = phi i32 [ [[SUB]], [[DO_BODY]] ] 177; CHECK-NEXT: ret i32 [[SUB_LCSSA]] 178; 179entry: 180 br label %do.body 181 182do.body: ; preds = %do.body, %entry 183 %S.addr.0 = phi i32 [ %S, %entry ], [ %sub, %do.body ] 184 %sub = add i32 %S.addr.0, -16 185 tail call void @call() 186 %cmp = icmp ugt i32 %sub, 15 187 br i1 %cmp, label %do.body, label %do.end 188 189do.end: ; preds = %do.body 190 %sub.lcssa = phi i32 [ %sub, %do.body ] 191 ret i32 %sub.lcssa 192} 193 194 195declare void @call() 196