1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=loop-unroll -S -unroll-threshold=120 -unroll-max-iteration-count-to-analyze=100 < %s | FileCheck %s 3 4; TODO: None of the if.false blocks are reachable, it would be nice if 5; the output of unrolling made this obvious and didn't rely on other 6; passes to cleanup code the cost model already knew was dead. 7 8@G = global i32 0 9 10; Symbolic simplification can prove the value of %zext on first 11; iteration, and can prove that it's loop invariant on the second 12define i32 @test_symbolic_simplify(i32 %limit) { 13; CHECK-LABEL: @test_symbolic_simplify( 14; CHECK-NEXT: entry: 15; CHECK-NEXT: br label [[LOOP:%.*]] 16; CHECK: loop: 17; CHECK-NEXT: store i32 -1, ptr @G, align 4 18; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i32 0, [[LIMIT:%.*]] 19; CHECK-NEXT: [[ZEXT_1:%.*]] = sext i1 [[CMP_1]] to i32 20; CHECK-NEXT: store i32 [[ZEXT_1]], ptr @G, align 4 21; CHECK-NEXT: [[CMP_2:%.*]] = icmp eq i32 0, [[LIMIT]] 22; CHECK-NEXT: [[ZEXT_2:%.*]] = sext i1 [[CMP_2]] to i32 23; CHECK-NEXT: store i32 [[ZEXT_2]], ptr @G, align 4 24; CHECK-NEXT: [[CMP_3:%.*]] = icmp eq i32 0, [[LIMIT]] 25; CHECK-NEXT: [[ZEXT_3:%.*]] = sext i1 [[CMP_3]] to i32 26; CHECK-NEXT: store i32 [[ZEXT_3]], ptr @G, align 4 27; CHECK-NEXT: [[CMP_4:%.*]] = icmp eq i32 0, [[LIMIT]] 28; CHECK-NEXT: [[ZEXT_4:%.*]] = sext i1 [[CMP_4]] to i32 29; CHECK-NEXT: store i32 [[ZEXT_4]], ptr @G, align 4 30; CHECK-NEXT: [[CMP_5:%.*]] = icmp eq i32 0, [[LIMIT]] 31; CHECK-NEXT: [[ZEXT_5:%.*]] = sext i1 [[CMP_5]] to i32 32; CHECK-NEXT: store i32 [[ZEXT_5]], ptr @G, align 4 33; CHECK-NEXT: [[CMP_6:%.*]] = icmp eq i32 0, [[LIMIT]] 34; CHECK-NEXT: [[ZEXT_6:%.*]] = sext i1 [[CMP_6]] to i32 35; CHECK-NEXT: store i32 [[ZEXT_6]], ptr @G, align 4 36; CHECK-NEXT: [[CMP_7:%.*]] = icmp eq i32 0, [[LIMIT]] 37; CHECK-NEXT: [[ZEXT_7:%.*]] = sext i1 [[CMP_7]] to i32 38; CHECK-NEXT: store i32 [[ZEXT_7]], ptr @G, align 4 39; CHECK-NEXT: [[CMP_8:%.*]] = icmp eq i32 0, [[LIMIT]] 40; CHECK-NEXT: [[ZEXT_8:%.*]] = sext i1 [[CMP_8]] to i32 41; CHECK-NEXT: store i32 [[ZEXT_8]], ptr @G, align 4 42; CHECK-NEXT: [[CMP_9:%.*]] = icmp eq i32 0, [[LIMIT]] 43; CHECK-NEXT: [[ZEXT_9:%.*]] = sext i1 [[CMP_9]] to i32 44; CHECK-NEXT: store i32 [[ZEXT_9]], ptr @G, align 4 45; CHECK-NEXT: [[CMP_10:%.*]] = icmp eq i32 0, [[LIMIT]] 46; CHECK-NEXT: [[ZEXT_10:%.*]] = sext i1 [[CMP_10]] to i32 47; CHECK-NEXT: store i32 [[ZEXT_10]], ptr @G, align 4 48; CHECK-NEXT: [[CMP_11:%.*]] = icmp eq i32 0, [[LIMIT]] 49; CHECK-NEXT: [[ZEXT_11:%.*]] = sext i1 [[CMP_11]] to i32 50; CHECK-NEXT: store i32 [[ZEXT_11]], ptr @G, align 4 51; CHECK-NEXT: [[CMP_12:%.*]] = icmp eq i32 0, [[LIMIT]] 52; CHECK-NEXT: [[ZEXT_12:%.*]] = sext i1 [[CMP_12]] to i32 53; CHECK-NEXT: store i32 [[ZEXT_12]], ptr @G, align 4 54; CHECK-NEXT: [[CMP_13:%.*]] = icmp eq i32 0, [[LIMIT]] 55; CHECK-NEXT: [[ZEXT_13:%.*]] = sext i1 [[CMP_13]] to i32 56; CHECK-NEXT: store i32 [[ZEXT_13]], ptr @G, align 4 57; CHECK-NEXT: [[CMP_14:%.*]] = icmp eq i32 0, [[LIMIT]] 58; CHECK-NEXT: [[ZEXT_14:%.*]] = sext i1 [[CMP_14]] to i32 59; CHECK-NEXT: store i32 [[ZEXT_14]], ptr @G, align 4 60; CHECK-NEXT: [[CMP_15:%.*]] = icmp eq i32 0, [[LIMIT]] 61; CHECK-NEXT: [[ZEXT_15:%.*]] = sext i1 [[CMP_15]] to i32 62; CHECK-NEXT: store i32 [[ZEXT_15]], ptr @G, align 4 63; CHECK-NEXT: [[CMP_16:%.*]] = icmp eq i32 0, [[LIMIT]] 64; CHECK-NEXT: [[ZEXT_16:%.*]] = sext i1 [[CMP_16]] to i32 65; CHECK-NEXT: store i32 [[ZEXT_16]], ptr @G, align 4 66; CHECK-NEXT: [[CMP_17:%.*]] = icmp eq i32 0, [[LIMIT]] 67; CHECK-NEXT: [[ZEXT_17:%.*]] = sext i1 [[CMP_17]] to i32 68; CHECK-NEXT: store i32 [[ZEXT_17]], ptr @G, align 4 69; CHECK-NEXT: [[CMP_18:%.*]] = icmp eq i32 0, [[LIMIT]] 70; CHECK-NEXT: [[ZEXT_18:%.*]] = sext i1 [[CMP_18]] to i32 71; CHECK-NEXT: store i32 [[ZEXT_18]], ptr @G, align 4 72; CHECK-NEXT: [[CMP_19:%.*]] = icmp eq i32 0, [[LIMIT]] 73; CHECK-NEXT: [[ZEXT_19:%.*]] = sext i1 [[CMP_19]] to i32 74; CHECK-NEXT: store i32 [[ZEXT_19]], ptr @G, align 4 75; CHECK-NEXT: [[CMP_20:%.*]] = icmp eq i32 0, [[LIMIT]] 76; CHECK-NEXT: [[ZEXT_20:%.*]] = sext i1 [[CMP_20]] to i32 77; CHECK-NEXT: store i32 [[ZEXT_20]], ptr @G, align 4 78; CHECK-NEXT: [[CMP_21:%.*]] = icmp eq i32 0, [[LIMIT]] 79; CHECK-NEXT: [[ZEXT_21:%.*]] = sext i1 [[CMP_21]] to i32 80; CHECK-NEXT: store i32 [[ZEXT_21]], ptr @G, align 4 81; CHECK-NEXT: [[CMP_22:%.*]] = icmp eq i32 0, [[LIMIT]] 82; CHECK-NEXT: [[ZEXT_22:%.*]] = sext i1 [[CMP_22]] to i32 83; CHECK-NEXT: store i32 [[ZEXT_22]], ptr @G, align 4 84; CHECK-NEXT: [[CMP_23:%.*]] = icmp eq i32 0, [[LIMIT]] 85; CHECK-NEXT: [[ZEXT_23:%.*]] = sext i1 [[CMP_23]] to i32 86; CHECK-NEXT: store i32 [[ZEXT_23]], ptr @G, align 4 87; CHECK-NEXT: [[CMP_24:%.*]] = icmp eq i32 0, [[LIMIT]] 88; CHECK-NEXT: [[ZEXT_24:%.*]] = sext i1 [[CMP_24]] to i32 89; CHECK-NEXT: store i32 [[ZEXT_24]], ptr @G, align 4 90; CHECK-NEXT: [[CMP_25:%.*]] = icmp eq i32 0, [[LIMIT]] 91; CHECK-NEXT: [[ZEXT_25:%.*]] = sext i1 [[CMP_25]] to i32 92; CHECK-NEXT: store i32 [[ZEXT_25]], ptr @G, align 4 93; CHECK-NEXT: [[CMP_26:%.*]] = icmp eq i32 0, [[LIMIT]] 94; CHECK-NEXT: [[ZEXT_26:%.*]] = sext i1 [[CMP_26]] to i32 95; CHECK-NEXT: store i32 [[ZEXT_26]], ptr @G, align 4 96; CHECK-NEXT: [[CMP_27:%.*]] = icmp eq i32 0, [[LIMIT]] 97; CHECK-NEXT: [[ZEXT_27:%.*]] = sext i1 [[CMP_27]] to i32 98; CHECK-NEXT: store i32 [[ZEXT_27]], ptr @G, align 4 99; CHECK-NEXT: [[CMP_28:%.*]] = icmp eq i32 0, [[LIMIT]] 100; CHECK-NEXT: [[ZEXT_28:%.*]] = sext i1 [[CMP_28]] to i32 101; CHECK-NEXT: store i32 [[ZEXT_28]], ptr @G, align 4 102; CHECK-NEXT: [[CMP_29:%.*]] = icmp eq i32 0, [[LIMIT]] 103; CHECK-NEXT: [[ZEXT_29:%.*]] = sext i1 [[CMP_29]] to i32 104; CHECK-NEXT: store i32 [[ZEXT_29]], ptr @G, align 4 105; CHECK-NEXT: [[CMP_30:%.*]] = icmp eq i32 0, [[LIMIT]] 106; CHECK-NEXT: [[ZEXT_30:%.*]] = sext i1 [[CMP_30]] to i32 107; CHECK-NEXT: store i32 [[ZEXT_30]], ptr @G, align 4 108; CHECK-NEXT: [[CMP_31:%.*]] = icmp eq i32 0, [[LIMIT]] 109; CHECK-NEXT: [[ZEXT_31:%.*]] = sext i1 [[CMP_31]] to i32 110; CHECK-NEXT: store i32 [[ZEXT_31]], ptr @G, align 4 111; CHECK-NEXT: [[CMP_32:%.*]] = icmp eq i32 0, [[LIMIT]] 112; CHECK-NEXT: [[ZEXT_32:%.*]] = sext i1 [[CMP_32]] to i32 113; CHECK-NEXT: store i32 [[ZEXT_32]], ptr @G, align 4 114; CHECK-NEXT: [[CMP_33:%.*]] = icmp eq i32 0, [[LIMIT]] 115; CHECK-NEXT: [[ZEXT_33:%.*]] = sext i1 [[CMP_33]] to i32 116; CHECK-NEXT: store i32 [[ZEXT_33]], ptr @G, align 4 117; CHECK-NEXT: [[CMP_34:%.*]] = icmp eq i32 0, [[LIMIT]] 118; CHECK-NEXT: [[ZEXT_34:%.*]] = sext i1 [[CMP_34]] to i32 119; CHECK-NEXT: store i32 [[ZEXT_34]], ptr @G, align 4 120; CHECK-NEXT: [[CMP_35:%.*]] = icmp eq i32 0, [[LIMIT]] 121; CHECK-NEXT: [[ZEXT_35:%.*]] = sext i1 [[CMP_35]] to i32 122; CHECK-NEXT: store i32 [[ZEXT_35]], ptr @G, align 4 123; CHECK-NEXT: [[CMP_36:%.*]] = icmp eq i32 0, [[LIMIT]] 124; CHECK-NEXT: [[ZEXT_36:%.*]] = sext i1 [[CMP_36]] to i32 125; CHECK-NEXT: store i32 [[ZEXT_36]], ptr @G, align 4 126; CHECK-NEXT: [[CMP_37:%.*]] = icmp eq i32 0, [[LIMIT]] 127; CHECK-NEXT: [[ZEXT_37:%.*]] = sext i1 [[CMP_37]] to i32 128; CHECK-NEXT: store i32 [[ZEXT_37]], ptr @G, align 4 129; CHECK-NEXT: [[CMP_38:%.*]] = icmp eq i32 0, [[LIMIT]] 130; CHECK-NEXT: [[ZEXT_38:%.*]] = sext i1 [[CMP_38]] to i32 131; CHECK-NEXT: store i32 [[ZEXT_38]], ptr @G, align 4 132; CHECK-NEXT: [[CMP_39:%.*]] = icmp eq i32 0, [[LIMIT]] 133; CHECK-NEXT: [[ZEXT_39:%.*]] = sext i1 [[CMP_39]] to i32 134; CHECK-NEXT: store i32 [[ZEXT_39]], ptr @G, align 4 135; CHECK-NEXT: [[CMP_40:%.*]] = icmp eq i32 0, [[LIMIT]] 136; CHECK-NEXT: [[ZEXT_40:%.*]] = sext i1 [[CMP_40]] to i32 137; CHECK-NEXT: store i32 [[ZEXT_40]], ptr @G, align 4 138; CHECK-NEXT: [[CMP_41:%.*]] = icmp eq i32 0, [[LIMIT]] 139; CHECK-NEXT: [[ZEXT_41:%.*]] = sext i1 [[CMP_41]] to i32 140; CHECK-NEXT: store i32 [[ZEXT_41]], ptr @G, align 4 141; CHECK-NEXT: [[CMP_42:%.*]] = icmp eq i32 0, [[LIMIT]] 142; CHECK-NEXT: [[ZEXT_42:%.*]] = sext i1 [[CMP_42]] to i32 143; CHECK-NEXT: store i32 [[ZEXT_42]], ptr @G, align 4 144; CHECK-NEXT: [[CMP_43:%.*]] = icmp eq i32 0, [[LIMIT]] 145; CHECK-NEXT: [[ZEXT_43:%.*]] = sext i1 [[CMP_43]] to i32 146; CHECK-NEXT: store i32 [[ZEXT_43]], ptr @G, align 4 147; CHECK-NEXT: [[CMP_44:%.*]] = icmp eq i32 0, [[LIMIT]] 148; CHECK-NEXT: [[ZEXT_44:%.*]] = sext i1 [[CMP_44]] to i32 149; CHECK-NEXT: store i32 [[ZEXT_44]], ptr @G, align 4 150; CHECK-NEXT: [[CMP_45:%.*]] = icmp eq i32 0, [[LIMIT]] 151; CHECK-NEXT: [[ZEXT_45:%.*]] = sext i1 [[CMP_45]] to i32 152; CHECK-NEXT: store i32 [[ZEXT_45]], ptr @G, align 4 153; CHECK-NEXT: [[CMP_46:%.*]] = icmp eq i32 0, [[LIMIT]] 154; CHECK-NEXT: [[ZEXT_46:%.*]] = sext i1 [[CMP_46]] to i32 155; CHECK-NEXT: store i32 [[ZEXT_46]], ptr @G, align 4 156; CHECK-NEXT: [[CMP_47:%.*]] = icmp eq i32 0, [[LIMIT]] 157; CHECK-NEXT: [[ZEXT_47:%.*]] = sext i1 [[CMP_47]] to i32 158; CHECK-NEXT: store i32 [[ZEXT_47]], ptr @G, align 4 159; CHECK-NEXT: [[CMP_48:%.*]] = icmp eq i32 0, [[LIMIT]] 160; CHECK-NEXT: [[ZEXT_48:%.*]] = sext i1 [[CMP_48]] to i32 161; CHECK-NEXT: store i32 [[ZEXT_48]], ptr @G, align 4 162; CHECK-NEXT: [[CMP_49:%.*]] = icmp eq i32 0, [[LIMIT]] 163; CHECK-NEXT: [[ZEXT_49:%.*]] = sext i1 [[CMP_49]] to i32 164; CHECK-NEXT: store i32 [[ZEXT_49]], ptr @G, align 4 165; CHECK-NEXT: [[CMP_50:%.*]] = icmp eq i32 0, [[LIMIT]] 166; CHECK-NEXT: [[ZEXT_50:%.*]] = sext i1 [[CMP_50]] to i32 167; CHECK-NEXT: store i32 [[ZEXT_50]], ptr @G, align 4 168; CHECK-NEXT: [[CMP_51:%.*]] = icmp eq i32 0, [[LIMIT]] 169; CHECK-NEXT: [[ZEXT_51:%.*]] = sext i1 [[CMP_51]] to i32 170; CHECK-NEXT: store i32 [[ZEXT_51]], ptr @G, align 4 171; CHECK-NEXT: [[CMP_52:%.*]] = icmp eq i32 0, [[LIMIT]] 172; CHECK-NEXT: [[ZEXT_52:%.*]] = sext i1 [[CMP_52]] to i32 173; CHECK-NEXT: store i32 [[ZEXT_52]], ptr @G, align 4 174; CHECK-NEXT: [[CMP_53:%.*]] = icmp eq i32 0, [[LIMIT]] 175; CHECK-NEXT: [[ZEXT_53:%.*]] = sext i1 [[CMP_53]] to i32 176; CHECK-NEXT: store i32 [[ZEXT_53]], ptr @G, align 4 177; CHECK-NEXT: [[CMP_54:%.*]] = icmp eq i32 0, [[LIMIT]] 178; CHECK-NEXT: [[ZEXT_54:%.*]] = sext i1 [[CMP_54]] to i32 179; CHECK-NEXT: store i32 [[ZEXT_54]], ptr @G, align 4 180; CHECK-NEXT: [[CMP_55:%.*]] = icmp eq i32 0, [[LIMIT]] 181; CHECK-NEXT: [[ZEXT_55:%.*]] = sext i1 [[CMP_55]] to i32 182; CHECK-NEXT: store i32 [[ZEXT_55]], ptr @G, align 4 183; CHECK-NEXT: [[CMP_56:%.*]] = icmp eq i32 0, [[LIMIT]] 184; CHECK-NEXT: [[ZEXT_56:%.*]] = sext i1 [[CMP_56]] to i32 185; CHECK-NEXT: store i32 [[ZEXT_56]], ptr @G, align 4 186; CHECK-NEXT: [[CMP_57:%.*]] = icmp eq i32 0, [[LIMIT]] 187; CHECK-NEXT: [[ZEXT_57:%.*]] = sext i1 [[CMP_57]] to i32 188; CHECK-NEXT: store i32 [[ZEXT_57]], ptr @G, align 4 189; CHECK-NEXT: [[CMP_58:%.*]] = icmp eq i32 0, [[LIMIT]] 190; CHECK-NEXT: [[ZEXT_58:%.*]] = sext i1 [[CMP_58]] to i32 191; CHECK-NEXT: store i32 [[ZEXT_58]], ptr @G, align 4 192; CHECK-NEXT: [[CMP_59:%.*]] = icmp eq i32 0, [[LIMIT]] 193; CHECK-NEXT: [[ZEXT_59:%.*]] = sext i1 [[CMP_59]] to i32 194; CHECK-NEXT: store i32 [[ZEXT_59]], ptr @G, align 4 195; CHECK-NEXT: [[CMP_60:%.*]] = icmp eq i32 0, [[LIMIT]] 196; CHECK-NEXT: [[ZEXT_60:%.*]] = sext i1 [[CMP_60]] to i32 197; CHECK-NEXT: store i32 [[ZEXT_60]], ptr @G, align 4 198; CHECK-NEXT: [[CMP_61:%.*]] = icmp eq i32 0, [[LIMIT]] 199; CHECK-NEXT: [[ZEXT_61:%.*]] = sext i1 [[CMP_61]] to i32 200; CHECK-NEXT: store i32 [[ZEXT_61]], ptr @G, align 4 201; CHECK-NEXT: [[CMP_62:%.*]] = icmp eq i32 0, [[LIMIT]] 202; CHECK-NEXT: [[ZEXT_62:%.*]] = sext i1 [[CMP_62]] to i32 203; CHECK-NEXT: store i32 [[ZEXT_62]], ptr @G, align 4 204; CHECK-NEXT: [[CMP_63:%.*]] = icmp eq i32 0, [[LIMIT]] 205; CHECK-NEXT: [[ZEXT_63:%.*]] = sext i1 [[CMP_63]] to i32 206; CHECK-NEXT: store i32 [[ZEXT_63]], ptr @G, align 4 207; CHECK-NEXT: [[CMP_64:%.*]] = icmp eq i32 0, [[LIMIT]] 208; CHECK-NEXT: [[ZEXT_64:%.*]] = sext i1 [[CMP_64]] to i32 209; CHECK-NEXT: store i32 [[ZEXT_64]], ptr @G, align 4 210; CHECK-NEXT: [[CMP_65:%.*]] = icmp eq i32 0, [[LIMIT]] 211; CHECK-NEXT: [[ZEXT_65:%.*]] = sext i1 [[CMP_65]] to i32 212; CHECK-NEXT: store i32 [[ZEXT_65]], ptr @G, align 4 213; CHECK-NEXT: [[CMP_66:%.*]] = icmp eq i32 0, [[LIMIT]] 214; CHECK-NEXT: [[ZEXT_66:%.*]] = sext i1 [[CMP_66]] to i32 215; CHECK-NEXT: store i32 [[ZEXT_66]], ptr @G, align 4 216; CHECK-NEXT: [[CMP_67:%.*]] = icmp eq i32 0, [[LIMIT]] 217; CHECK-NEXT: [[ZEXT_67:%.*]] = sext i1 [[CMP_67]] to i32 218; CHECK-NEXT: store i32 [[ZEXT_67]], ptr @G, align 4 219; CHECK-NEXT: [[CMP_68:%.*]] = icmp eq i32 0, [[LIMIT]] 220; CHECK-NEXT: [[ZEXT_68:%.*]] = sext i1 [[CMP_68]] to i32 221; CHECK-NEXT: store i32 [[ZEXT_68]], ptr @G, align 4 222; CHECK-NEXT: [[CMP_69:%.*]] = icmp eq i32 0, [[LIMIT]] 223; CHECK-NEXT: [[ZEXT_69:%.*]] = sext i1 [[CMP_69]] to i32 224; CHECK-NEXT: store i32 [[ZEXT_69]], ptr @G, align 4 225; CHECK-NEXT: [[CMP_70:%.*]] = icmp eq i32 0, [[LIMIT]] 226; CHECK-NEXT: [[ZEXT_70:%.*]] = sext i1 [[CMP_70]] to i32 227; CHECK-NEXT: store i32 [[ZEXT_70]], ptr @G, align 4 228; CHECK-NEXT: [[CMP_71:%.*]] = icmp eq i32 0, [[LIMIT]] 229; CHECK-NEXT: [[ZEXT_71:%.*]] = sext i1 [[CMP_71]] to i32 230; CHECK-NEXT: store i32 [[ZEXT_71]], ptr @G, align 4 231; CHECK-NEXT: [[CMP_72:%.*]] = icmp eq i32 0, [[LIMIT]] 232; CHECK-NEXT: [[ZEXT_72:%.*]] = sext i1 [[CMP_72]] to i32 233; CHECK-NEXT: store i32 [[ZEXT_72]], ptr @G, align 4 234; CHECK-NEXT: [[CMP_73:%.*]] = icmp eq i32 0, [[LIMIT]] 235; CHECK-NEXT: [[ZEXT_73:%.*]] = sext i1 [[CMP_73]] to i32 236; CHECK-NEXT: store i32 [[ZEXT_73]], ptr @G, align 4 237; CHECK-NEXT: [[CMP_74:%.*]] = icmp eq i32 0, [[LIMIT]] 238; CHECK-NEXT: [[ZEXT_74:%.*]] = sext i1 [[CMP_74]] to i32 239; CHECK-NEXT: store i32 [[ZEXT_74]], ptr @G, align 4 240; CHECK-NEXT: [[CMP_75:%.*]] = icmp eq i32 0, [[LIMIT]] 241; CHECK-NEXT: [[ZEXT_75:%.*]] = sext i1 [[CMP_75]] to i32 242; CHECK-NEXT: store i32 [[ZEXT_75]], ptr @G, align 4 243; CHECK-NEXT: [[CMP_76:%.*]] = icmp eq i32 0, [[LIMIT]] 244; CHECK-NEXT: [[ZEXT_76:%.*]] = sext i1 [[CMP_76]] to i32 245; CHECK-NEXT: store i32 [[ZEXT_76]], ptr @G, align 4 246; CHECK-NEXT: [[CMP_77:%.*]] = icmp eq i32 0, [[LIMIT]] 247; CHECK-NEXT: [[ZEXT_77:%.*]] = sext i1 [[CMP_77]] to i32 248; CHECK-NEXT: store i32 [[ZEXT_77]], ptr @G, align 4 249; CHECK-NEXT: [[CMP_78:%.*]] = icmp eq i32 0, [[LIMIT]] 250; CHECK-NEXT: [[ZEXT_78:%.*]] = sext i1 [[CMP_78]] to i32 251; CHECK-NEXT: store i32 [[ZEXT_78]], ptr @G, align 4 252; CHECK-NEXT: [[CMP_79:%.*]] = icmp eq i32 0, [[LIMIT]] 253; CHECK-NEXT: [[ZEXT_79:%.*]] = sext i1 [[CMP_79]] to i32 254; CHECK-NEXT: store i32 [[ZEXT_79]], ptr @G, align 4 255; CHECK-NEXT: [[CMP_80:%.*]] = icmp eq i32 0, [[LIMIT]] 256; CHECK-NEXT: [[ZEXT_80:%.*]] = sext i1 [[CMP_80]] to i32 257; CHECK-NEXT: store i32 [[ZEXT_80]], ptr @G, align 4 258; CHECK-NEXT: ret i32 [[ZEXT_80]] 259; 260entry: 261 br label %loop 262 263loop: ; preds = %backedge, %entry 264 %phi = phi i32 [ 0, %entry ], [ %limit, %loop ] 265 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 266 %sub = sub i32 %limit, %phi 267 %cmp = icmp eq i32 %sub, %limit 268 %zext = sext i1 %cmp to i32 269 store i32 %zext, ptr @G 270 %iv.next = add i32 %iv, 1 271 %loop.cond = icmp ne i32 %iv, 80 272 br i1 %loop.cond, label %loop, label %done 273 274done: ; preds = %backedge 275 ret i32 %zext 276} 277 278; Use symbolic value facts to prune unreachable (expensive) paths 279; through the loop. 280define i32 @test_symbolic_path(i32 %limit) { 281; CHECK-LABEL: @test_symbolic_path( 282; CHECK-NEXT: entry: 283; CHECK-NEXT: br label [[LOOP:%.*]] 284; CHECK: loop: 285; CHECK-NEXT: br i1 true, label [[BACKEDGE:%.*]], label [[IF_FALSE:%.*]] 286; CHECK: if.false: 287; CHECK-NEXT: call void @foo() 288; CHECK-NEXT: call void @foo() 289; CHECK-NEXT: call void @foo() 290; CHECK-NEXT: call void @foo() 291; CHECK-NEXT: call void @foo() 292; CHECK-NEXT: call void @foo() 293; CHECK-NEXT: call void @foo() 294; CHECK-NEXT: call void @foo() 295; CHECK-NEXT: call void @foo() 296; CHECK-NEXT: call void @foo() 297; CHECK-NEXT: call void @foo() 298; CHECK-NEXT: call void @foo() 299; CHECK-NEXT: call void @foo() 300; CHECK-NEXT: call void @foo() 301; CHECK-NEXT: br label [[BACKEDGE]] 302; CHECK: backedge: 303; CHECK-NEXT: br i1 true, label [[BACKEDGE_1:%.*]], label [[IF_FALSE_1:%.*]] 304; CHECK: if.false.1: 305; CHECK-NEXT: call void @foo() 306; CHECK-NEXT: call void @foo() 307; CHECK-NEXT: call void @foo() 308; CHECK-NEXT: call void @foo() 309; CHECK-NEXT: call void @foo() 310; CHECK-NEXT: call void @foo() 311; CHECK-NEXT: call void @foo() 312; CHECK-NEXT: call void @foo() 313; CHECK-NEXT: call void @foo() 314; CHECK-NEXT: call void @foo() 315; CHECK-NEXT: call void @foo() 316; CHECK-NEXT: call void @foo() 317; CHECK-NEXT: call void @foo() 318; CHECK-NEXT: call void @foo() 319; CHECK-NEXT: br label [[BACKEDGE_1]] 320; CHECK: backedge.1: 321; CHECK-NEXT: br i1 true, label [[BACKEDGE_2:%.*]], label [[IF_FALSE_2:%.*]] 322; CHECK: if.false.2: 323; CHECK-NEXT: call void @foo() 324; CHECK-NEXT: call void @foo() 325; CHECK-NEXT: call void @foo() 326; CHECK-NEXT: call void @foo() 327; CHECK-NEXT: call void @foo() 328; CHECK-NEXT: call void @foo() 329; CHECK-NEXT: call void @foo() 330; CHECK-NEXT: call void @foo() 331; CHECK-NEXT: call void @foo() 332; CHECK-NEXT: call void @foo() 333; CHECK-NEXT: call void @foo() 334; CHECK-NEXT: call void @foo() 335; CHECK-NEXT: call void @foo() 336; CHECK-NEXT: call void @foo() 337; CHECK-NEXT: br label [[BACKEDGE_2]] 338; CHECK: backedge.2: 339; CHECK-NEXT: br i1 true, label [[BACKEDGE_3:%.*]], label [[IF_FALSE_3:%.*]] 340; CHECK: if.false.3: 341; CHECK-NEXT: call void @foo() 342; CHECK-NEXT: call void @foo() 343; CHECK-NEXT: call void @foo() 344; CHECK-NEXT: call void @foo() 345; CHECK-NEXT: call void @foo() 346; CHECK-NEXT: call void @foo() 347; CHECK-NEXT: call void @foo() 348; CHECK-NEXT: call void @foo() 349; CHECK-NEXT: call void @foo() 350; CHECK-NEXT: call void @foo() 351; CHECK-NEXT: call void @foo() 352; CHECK-NEXT: call void @foo() 353; CHECK-NEXT: call void @foo() 354; CHECK-NEXT: call void @foo() 355; CHECK-NEXT: br label [[BACKEDGE_3]] 356; CHECK: backedge.3: 357; CHECK-NEXT: br i1 true, label [[BACKEDGE_4:%.*]], label [[IF_FALSE_4:%.*]] 358; CHECK: if.false.4: 359; CHECK-NEXT: call void @foo() 360; CHECK-NEXT: call void @foo() 361; CHECK-NEXT: call void @foo() 362; CHECK-NEXT: call void @foo() 363; CHECK-NEXT: call void @foo() 364; CHECK-NEXT: call void @foo() 365; CHECK-NEXT: call void @foo() 366; CHECK-NEXT: call void @foo() 367; CHECK-NEXT: call void @foo() 368; CHECK-NEXT: call void @foo() 369; CHECK-NEXT: call void @foo() 370; CHECK-NEXT: call void @foo() 371; CHECK-NEXT: call void @foo() 372; CHECK-NEXT: call void @foo() 373; CHECK-NEXT: br label [[BACKEDGE_4]] 374; CHECK: backedge.4: 375; CHECK-NEXT: br i1 true, label [[BACKEDGE_5:%.*]], label [[IF_FALSE_5:%.*]] 376; CHECK: if.false.5: 377; CHECK-NEXT: call void @foo() 378; CHECK-NEXT: call void @foo() 379; CHECK-NEXT: call void @foo() 380; CHECK-NEXT: call void @foo() 381; CHECK-NEXT: call void @foo() 382; CHECK-NEXT: call void @foo() 383; CHECK-NEXT: call void @foo() 384; CHECK-NEXT: call void @foo() 385; CHECK-NEXT: call void @foo() 386; CHECK-NEXT: call void @foo() 387; CHECK-NEXT: call void @foo() 388; CHECK-NEXT: call void @foo() 389; CHECK-NEXT: call void @foo() 390; CHECK-NEXT: call void @foo() 391; CHECK-NEXT: br label [[BACKEDGE_5]] 392; CHECK: backedge.5: 393; CHECK-NEXT: br i1 true, label [[BACKEDGE_6:%.*]], label [[IF_FALSE_6:%.*]] 394; CHECK: if.false.6: 395; CHECK-NEXT: call void @foo() 396; CHECK-NEXT: call void @foo() 397; CHECK-NEXT: call void @foo() 398; CHECK-NEXT: call void @foo() 399; CHECK-NEXT: call void @foo() 400; CHECK-NEXT: call void @foo() 401; CHECK-NEXT: call void @foo() 402; CHECK-NEXT: call void @foo() 403; CHECK-NEXT: call void @foo() 404; CHECK-NEXT: call void @foo() 405; CHECK-NEXT: call void @foo() 406; CHECK-NEXT: call void @foo() 407; CHECK-NEXT: call void @foo() 408; CHECK-NEXT: call void @foo() 409; CHECK-NEXT: br label [[BACKEDGE_6]] 410; CHECK: backedge.6: 411; CHECK-NEXT: br i1 true, label [[BACKEDGE_7:%.*]], label [[IF_FALSE_7:%.*]] 412; CHECK: if.false.7: 413; CHECK-NEXT: call void @foo() 414; CHECK-NEXT: call void @foo() 415; CHECK-NEXT: call void @foo() 416; CHECK-NEXT: call void @foo() 417; CHECK-NEXT: call void @foo() 418; CHECK-NEXT: call void @foo() 419; CHECK-NEXT: call void @foo() 420; CHECK-NEXT: call void @foo() 421; CHECK-NEXT: call void @foo() 422; CHECK-NEXT: call void @foo() 423; CHECK-NEXT: call void @foo() 424; CHECK-NEXT: call void @foo() 425; CHECK-NEXT: call void @foo() 426; CHECK-NEXT: call void @foo() 427; CHECK-NEXT: br label [[BACKEDGE_7]] 428; CHECK: backedge.7: 429; CHECK-NEXT: br i1 true, label [[BACKEDGE_8:%.*]], label [[IF_FALSE_8:%.*]] 430; CHECK: if.false.8: 431; CHECK-NEXT: call void @foo() 432; CHECK-NEXT: call void @foo() 433; CHECK-NEXT: call void @foo() 434; CHECK-NEXT: call void @foo() 435; CHECK-NEXT: call void @foo() 436; CHECK-NEXT: call void @foo() 437; CHECK-NEXT: call void @foo() 438; CHECK-NEXT: call void @foo() 439; CHECK-NEXT: call void @foo() 440; CHECK-NEXT: call void @foo() 441; CHECK-NEXT: call void @foo() 442; CHECK-NEXT: call void @foo() 443; CHECK-NEXT: call void @foo() 444; CHECK-NEXT: call void @foo() 445; CHECK-NEXT: br label [[BACKEDGE_8]] 446; CHECK: backedge.8: 447; CHECK-NEXT: ret i32 0 448; 449entry: 450 br label %loop 451 452loop: ; preds = %backedge, %entry 453 %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ] 454 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] 455 %sub = sub i32 %limit, %sum 456 %is.positive = icmp eq i32 %sub, %limit 457 br i1 %is.positive, label %backedge, label %if.false 458 459if.false: ; preds = %loop 460 call void @foo() 461 call void @foo() 462 call void @foo() 463 call void @foo() 464 call void @foo() 465 call void @foo() 466 call void @foo() 467 call void @foo() 468 call void @foo() 469 call void @foo() 470 call void @foo() 471 call void @foo() 472 call void @foo() 473 call void @foo() 474 br label %backedge 475 476backedge: ; preds = %if.false, %loop 477 %hidden_zero = sub i32 %limit, %sub 478 %sum.next = add i32 %sum, %hidden_zero 479 %iv.next = add i32 %iv, 1 480 %loop.cond = icmp ne i32 %iv, 8 481 br i1 %loop.cond, label %loop, label %done 482 483done: ; preds = %backedge 484 %sum.next.lcssa = phi i32 [ %sum.next, %backedge ] 485 ret i32 %sum.next.lcssa 486} 487 488; A test to show the ability to simplify branches (even without general 489; symbolic execution of the loop beyond constants) is still useful. 490define i32 @test_dom_condition(i32 %limit) { 491; CHECK-LABEL: @test_dom_condition( 492; CHECK-NEXT: entry: 493; CHECK-NEXT: [[LOOP_GUARD:%.*]] = icmp sge i32 [[LIMIT:%.*]], 0 494; CHECK-NEXT: br i1 [[LOOP_GUARD]], label [[LOOP_PREHEADER:%.*]], label [[FAILURE:%.*]] 495; CHECK: loop.preheader: 496; CHECK-NEXT: br label [[LOOP:%.*]] 497; CHECK: loop: 498; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 499; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE]] ], [ 0, [[LOOP_PREHEADER]] ] 500; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[SUM]] 501; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sle i32 [[SUB]], [[LIMIT]] 502; CHECK-NEXT: br i1 [[IS_POSITIVE]], label [[BACKEDGE]], label [[IF_FALSE:%.*]] 503; CHECK: if.false: 504; CHECK-NEXT: call void @foo() 505; CHECK-NEXT: call void @foo() 506; CHECK-NEXT: call void @foo() 507; CHECK-NEXT: call void @foo() 508; CHECK-NEXT: call void @foo() 509; CHECK-NEXT: call void @foo() 510; CHECK-NEXT: call void @foo() 511; CHECK-NEXT: call void @foo() 512; CHECK-NEXT: call void @foo() 513; CHECK-NEXT: call void @foo() 514; CHECK-NEXT: call void @foo() 515; CHECK-NEXT: call void @foo() 516; CHECK-NEXT: call void @foo() 517; CHECK-NEXT: call void @foo() 518; CHECK-NEXT: br label [[BACKEDGE]] 519; CHECK: backedge: 520; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[SUB]] 521; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 522; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 8 523; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]] 524; CHECK: done: 525; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ] 526; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 527; CHECK: failure: 528; CHECK-NEXT: unreachable 529; 530entry: 531 %loop_guard = icmp sge i32 %limit, 0 532 br i1 %loop_guard, label %loop, label %failure 533 534loop: ; preds = %backedge, %entry 535 %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ] 536 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] 537 %sub = sub i32 0, %sum 538 %is.positive = icmp sle i32 %sub, %limit 539 br i1 %is.positive, label %backedge, label %if.false 540 541if.false: ; preds = %loop 542 call void @foo() 543 call void @foo() 544 call void @foo() 545 call void @foo() 546 call void @foo() 547 call void @foo() 548 call void @foo() 549 call void @foo() 550 call void @foo() 551 call void @foo() 552 call void @foo() 553 call void @foo() 554 call void @foo() 555 call void @foo() 556 br label %backedge 557 558backedge: ; preds = %if.false, %loop 559 %sum.next = add i32 %sum, %sub 560 %iv.next = add i32 %iv, 1 561 %loop.cond = icmp ne i32 %iv, 8 562 br i1 %loop.cond, label %loop, label %done 563 564done: ; preds = %backedge 565 %sum.next.lcssa = phi i32 [ %sum.next, %backedge ] 566 ret i32 %sum.next.lcssa 567 568failure: 569 unreachable 570} 571 572; We can symbolically evaluate %sub to %limit on first iteration, and 573; to zero on all future iterations. 574define i32 @test_both(i32 %limit) { 575; CHECK-LABEL: @test_both( 576; CHECK-NEXT: entry: 577; CHECK-NEXT: [[LOOP_GUARD:%.*]] = icmp sge i32 [[LIMIT:%.*]], 0 578; CHECK-NEXT: br i1 [[LOOP_GUARD]], label [[LOOP_PREHEADER:%.*]], label [[FAILURE:%.*]] 579; CHECK: loop.preheader: 580; CHECK-NEXT: br label [[LOOP:%.*]] 581; CHECK: loop: 582; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 583; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE]] ], [ 0, [[LOOP_PREHEADER]] ] 584; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[LIMIT]], [[SUM]] 585; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sge i32 [[SUB]], 0 586; CHECK-NEXT: br i1 [[IS_POSITIVE]], label [[BACKEDGE]], label [[IF_FALSE:%.*]] 587; CHECK: if.false: 588; CHECK-NEXT: call void @foo() 589; CHECK-NEXT: call void @foo() 590; CHECK-NEXT: call void @foo() 591; CHECK-NEXT: call void @foo() 592; CHECK-NEXT: call void @foo() 593; CHECK-NEXT: call void @foo() 594; CHECK-NEXT: call void @foo() 595; CHECK-NEXT: call void @foo() 596; CHECK-NEXT: call void @foo() 597; CHECK-NEXT: call void @foo() 598; CHECK-NEXT: call void @foo() 599; CHECK-NEXT: call void @foo() 600; CHECK-NEXT: call void @foo() 601; CHECK-NEXT: call void @foo() 602; CHECK-NEXT: br label [[BACKEDGE]] 603; CHECK: backedge: 604; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[SUB]] 605; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 606; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 8 607; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]] 608; CHECK: done: 609; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ] 610; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 611; CHECK: failure: 612; CHECK-NEXT: unreachable 613; 614entry: 615 %loop_guard = icmp sge i32 %limit, 0 616 br i1 %loop_guard, label %loop, label %failure 617 618loop: ; preds = %backedge, %entry 619 %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ] 620 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] 621 %sub = sub i32 %limit, %sum 622 %is.positive = icmp sge i32 %sub, 0 623 br i1 %is.positive, label %backedge, label %if.false 624 625if.false: ; preds = %loop 626 call void @foo() 627 call void @foo() 628 call void @foo() 629 call void @foo() 630 call void @foo() 631 call void @foo() 632 call void @foo() 633 call void @foo() 634 call void @foo() 635 call void @foo() 636 call void @foo() 637 call void @foo() 638 call void @foo() 639 call void @foo() 640 br label %backedge 641 642backedge: ; preds = %if.false, %loop 643 %sum.next = add i32 %sum, %sub 644 %iv.next = add i32 %iv, 1 645 %loop.cond = icmp ne i32 %iv, 8 646 br i1 %loop.cond, label %loop, label %done 647 648done: ; preds = %backedge 649 %sum.next.lcssa = phi i32 [ %sum.next, %backedge ] 650 ret i32 %sum.next.lcssa 651 652failure: 653 unreachable 654} 655 656declare void @foo() 657