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