657 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=loop-unroll -S -unroll-threshold=120 -unroll-max-iteration-count-to-analyze=100 < %s | FileCheck %s3 4; TODO: None of the if.false blocks are reachable, it would be nice if5; the output of unrolling made this obvious and didn't rely on other6; passes to cleanup code the cost model already knew was dead.7 8@G = global i32 09 10; Symbolic simplification can prove the value of %zext on first11; iteration, and can prove that it's loop invariant on the second12define 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 418; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i32 0, [[LIMIT:%.*]]19; CHECK-NEXT: [[ZEXT_1:%.*]] = sext i1 [[CMP_1]] to i3220; CHECK-NEXT: store i32 [[ZEXT_1]], ptr @G, align 421; CHECK-NEXT: [[CMP_2:%.*]] = icmp eq i32 0, [[LIMIT]]22; CHECK-NEXT: [[ZEXT_2:%.*]] = sext i1 [[CMP_2]] to i3223; CHECK-NEXT: store i32 [[ZEXT_2]], ptr @G, align 424; CHECK-NEXT: [[CMP_3:%.*]] = icmp eq i32 0, [[LIMIT]]25; CHECK-NEXT: [[ZEXT_3:%.*]] = sext i1 [[CMP_3]] to i3226; CHECK-NEXT: store i32 [[ZEXT_3]], ptr @G, align 427; CHECK-NEXT: [[CMP_4:%.*]] = icmp eq i32 0, [[LIMIT]]28; CHECK-NEXT: [[ZEXT_4:%.*]] = sext i1 [[CMP_4]] to i3229; CHECK-NEXT: store i32 [[ZEXT_4]], ptr @G, align 430; CHECK-NEXT: [[CMP_5:%.*]] = icmp eq i32 0, [[LIMIT]]31; CHECK-NEXT: [[ZEXT_5:%.*]] = sext i1 [[CMP_5]] to i3232; CHECK-NEXT: store i32 [[ZEXT_5]], ptr @G, align 433; CHECK-NEXT: [[CMP_6:%.*]] = icmp eq i32 0, [[LIMIT]]34; CHECK-NEXT: [[ZEXT_6:%.*]] = sext i1 [[CMP_6]] to i3235; CHECK-NEXT: store i32 [[ZEXT_6]], ptr @G, align 436; CHECK-NEXT: [[CMP_7:%.*]] = icmp eq i32 0, [[LIMIT]]37; CHECK-NEXT: [[ZEXT_7:%.*]] = sext i1 [[CMP_7]] to i3238; CHECK-NEXT: store i32 [[ZEXT_7]], ptr @G, align 439; CHECK-NEXT: [[CMP_8:%.*]] = icmp eq i32 0, [[LIMIT]]40; CHECK-NEXT: [[ZEXT_8:%.*]] = sext i1 [[CMP_8]] to i3241; CHECK-NEXT: store i32 [[ZEXT_8]], ptr @G, align 442; CHECK-NEXT: [[CMP_9:%.*]] = icmp eq i32 0, [[LIMIT]]43; CHECK-NEXT: [[ZEXT_9:%.*]] = sext i1 [[CMP_9]] to i3244; CHECK-NEXT: store i32 [[ZEXT_9]], ptr @G, align 445; CHECK-NEXT: [[CMP_10:%.*]] = icmp eq i32 0, [[LIMIT]]46; CHECK-NEXT: [[ZEXT_10:%.*]] = sext i1 [[CMP_10]] to i3247; CHECK-NEXT: store i32 [[ZEXT_10]], ptr @G, align 448; CHECK-NEXT: [[CMP_11:%.*]] = icmp eq i32 0, [[LIMIT]]49; CHECK-NEXT: [[ZEXT_11:%.*]] = sext i1 [[CMP_11]] to i3250; CHECK-NEXT: store i32 [[ZEXT_11]], ptr @G, align 451; CHECK-NEXT: [[CMP_12:%.*]] = icmp eq i32 0, [[LIMIT]]52; CHECK-NEXT: [[ZEXT_12:%.*]] = sext i1 [[CMP_12]] to i3253; CHECK-NEXT: store i32 [[ZEXT_12]], ptr @G, align 454; CHECK-NEXT: [[CMP_13:%.*]] = icmp eq i32 0, [[LIMIT]]55; CHECK-NEXT: [[ZEXT_13:%.*]] = sext i1 [[CMP_13]] to i3256; CHECK-NEXT: store i32 [[ZEXT_13]], ptr @G, align 457; CHECK-NEXT: [[CMP_14:%.*]] = icmp eq i32 0, [[LIMIT]]58; CHECK-NEXT: [[ZEXT_14:%.*]] = sext i1 [[CMP_14]] to i3259; CHECK-NEXT: store i32 [[ZEXT_14]], ptr @G, align 460; CHECK-NEXT: [[CMP_15:%.*]] = icmp eq i32 0, [[LIMIT]]61; CHECK-NEXT: [[ZEXT_15:%.*]] = sext i1 [[CMP_15]] to i3262; CHECK-NEXT: store i32 [[ZEXT_15]], ptr @G, align 463; CHECK-NEXT: [[CMP_16:%.*]] = icmp eq i32 0, [[LIMIT]]64; CHECK-NEXT: [[ZEXT_16:%.*]] = sext i1 [[CMP_16]] to i3265; CHECK-NEXT: store i32 [[ZEXT_16]], ptr @G, align 466; CHECK-NEXT: [[CMP_17:%.*]] = icmp eq i32 0, [[LIMIT]]67; CHECK-NEXT: [[ZEXT_17:%.*]] = sext i1 [[CMP_17]] to i3268; CHECK-NEXT: store i32 [[ZEXT_17]], ptr @G, align 469; CHECK-NEXT: [[CMP_18:%.*]] = icmp eq i32 0, [[LIMIT]]70; CHECK-NEXT: [[ZEXT_18:%.*]] = sext i1 [[CMP_18]] to i3271; CHECK-NEXT: store i32 [[ZEXT_18]], ptr @G, align 472; CHECK-NEXT: [[CMP_19:%.*]] = icmp eq i32 0, [[LIMIT]]73; CHECK-NEXT: [[ZEXT_19:%.*]] = sext i1 [[CMP_19]] to i3274; CHECK-NEXT: store i32 [[ZEXT_19]], ptr @G, align 475; CHECK-NEXT: [[CMP_20:%.*]] = icmp eq i32 0, [[LIMIT]]76; CHECK-NEXT: [[ZEXT_20:%.*]] = sext i1 [[CMP_20]] to i3277; CHECK-NEXT: store i32 [[ZEXT_20]], ptr @G, align 478; CHECK-NEXT: [[CMP_21:%.*]] = icmp eq i32 0, [[LIMIT]]79; CHECK-NEXT: [[ZEXT_21:%.*]] = sext i1 [[CMP_21]] to i3280; CHECK-NEXT: store i32 [[ZEXT_21]], ptr @G, align 481; CHECK-NEXT: [[CMP_22:%.*]] = icmp eq i32 0, [[LIMIT]]82; CHECK-NEXT: [[ZEXT_22:%.*]] = sext i1 [[CMP_22]] to i3283; CHECK-NEXT: store i32 [[ZEXT_22]], ptr @G, align 484; CHECK-NEXT: [[CMP_23:%.*]] = icmp eq i32 0, [[LIMIT]]85; CHECK-NEXT: [[ZEXT_23:%.*]] = sext i1 [[CMP_23]] to i3286; CHECK-NEXT: store i32 [[ZEXT_23]], ptr @G, align 487; CHECK-NEXT: [[CMP_24:%.*]] = icmp eq i32 0, [[LIMIT]]88; CHECK-NEXT: [[ZEXT_24:%.*]] = sext i1 [[CMP_24]] to i3289; CHECK-NEXT: store i32 [[ZEXT_24]], ptr @G, align 490; CHECK-NEXT: [[CMP_25:%.*]] = icmp eq i32 0, [[LIMIT]]91; CHECK-NEXT: [[ZEXT_25:%.*]] = sext i1 [[CMP_25]] to i3292; CHECK-NEXT: store i32 [[ZEXT_25]], ptr @G, align 493; CHECK-NEXT: [[CMP_26:%.*]] = icmp eq i32 0, [[LIMIT]]94; CHECK-NEXT: [[ZEXT_26:%.*]] = sext i1 [[CMP_26]] to i3295; CHECK-NEXT: store i32 [[ZEXT_26]], ptr @G, align 496; CHECK-NEXT: [[CMP_27:%.*]] = icmp eq i32 0, [[LIMIT]]97; CHECK-NEXT: [[ZEXT_27:%.*]] = sext i1 [[CMP_27]] to i3298; CHECK-NEXT: store i32 [[ZEXT_27]], ptr @G, align 499; CHECK-NEXT: [[CMP_28:%.*]] = icmp eq i32 0, [[LIMIT]]100; CHECK-NEXT: [[ZEXT_28:%.*]] = sext i1 [[CMP_28]] to i32101; CHECK-NEXT: store i32 [[ZEXT_28]], ptr @G, align 4102; CHECK-NEXT: [[CMP_29:%.*]] = icmp eq i32 0, [[LIMIT]]103; CHECK-NEXT: [[ZEXT_29:%.*]] = sext i1 [[CMP_29]] to i32104; CHECK-NEXT: store i32 [[ZEXT_29]], ptr @G, align 4105; CHECK-NEXT: [[CMP_30:%.*]] = icmp eq i32 0, [[LIMIT]]106; CHECK-NEXT: [[ZEXT_30:%.*]] = sext i1 [[CMP_30]] to i32107; CHECK-NEXT: store i32 [[ZEXT_30]], ptr @G, align 4108; CHECK-NEXT: [[CMP_31:%.*]] = icmp eq i32 0, [[LIMIT]]109; CHECK-NEXT: [[ZEXT_31:%.*]] = sext i1 [[CMP_31]] to i32110; CHECK-NEXT: store i32 [[ZEXT_31]], ptr @G, align 4111; CHECK-NEXT: [[CMP_32:%.*]] = icmp eq i32 0, [[LIMIT]]112; CHECK-NEXT: [[ZEXT_32:%.*]] = sext i1 [[CMP_32]] to i32113; CHECK-NEXT: store i32 [[ZEXT_32]], ptr @G, align 4114; CHECK-NEXT: [[CMP_33:%.*]] = icmp eq i32 0, [[LIMIT]]115; CHECK-NEXT: [[ZEXT_33:%.*]] = sext i1 [[CMP_33]] to i32116; CHECK-NEXT: store i32 [[ZEXT_33]], ptr @G, align 4117; CHECK-NEXT: [[CMP_34:%.*]] = icmp eq i32 0, [[LIMIT]]118; CHECK-NEXT: [[ZEXT_34:%.*]] = sext i1 [[CMP_34]] to i32119; CHECK-NEXT: store i32 [[ZEXT_34]], ptr @G, align 4120; CHECK-NEXT: [[CMP_35:%.*]] = icmp eq i32 0, [[LIMIT]]121; CHECK-NEXT: [[ZEXT_35:%.*]] = sext i1 [[CMP_35]] to i32122; CHECK-NEXT: store i32 [[ZEXT_35]], ptr @G, align 4123; CHECK-NEXT: [[CMP_36:%.*]] = icmp eq i32 0, [[LIMIT]]124; CHECK-NEXT: [[ZEXT_36:%.*]] = sext i1 [[CMP_36]] to i32125; CHECK-NEXT: store i32 [[ZEXT_36]], ptr @G, align 4126; CHECK-NEXT: [[CMP_37:%.*]] = icmp eq i32 0, [[LIMIT]]127; CHECK-NEXT: [[ZEXT_37:%.*]] = sext i1 [[CMP_37]] to i32128; CHECK-NEXT: store i32 [[ZEXT_37]], ptr @G, align 4129; CHECK-NEXT: [[CMP_38:%.*]] = icmp eq i32 0, [[LIMIT]]130; CHECK-NEXT: [[ZEXT_38:%.*]] = sext i1 [[CMP_38]] to i32131; CHECK-NEXT: store i32 [[ZEXT_38]], ptr @G, align 4132; CHECK-NEXT: [[CMP_39:%.*]] = icmp eq i32 0, [[LIMIT]]133; CHECK-NEXT: [[ZEXT_39:%.*]] = sext i1 [[CMP_39]] to i32134; CHECK-NEXT: store i32 [[ZEXT_39]], ptr @G, align 4135; CHECK-NEXT: [[CMP_40:%.*]] = icmp eq i32 0, [[LIMIT]]136; CHECK-NEXT: [[ZEXT_40:%.*]] = sext i1 [[CMP_40]] to i32137; CHECK-NEXT: store i32 [[ZEXT_40]], ptr @G, align 4138; CHECK-NEXT: [[CMP_41:%.*]] = icmp eq i32 0, [[LIMIT]]139; CHECK-NEXT: [[ZEXT_41:%.*]] = sext i1 [[CMP_41]] to i32140; CHECK-NEXT: store i32 [[ZEXT_41]], ptr @G, align 4141; CHECK-NEXT: [[CMP_42:%.*]] = icmp eq i32 0, [[LIMIT]]142; CHECK-NEXT: [[ZEXT_42:%.*]] = sext i1 [[CMP_42]] to i32143; CHECK-NEXT: store i32 [[ZEXT_42]], ptr @G, align 4144; CHECK-NEXT: [[CMP_43:%.*]] = icmp eq i32 0, [[LIMIT]]145; CHECK-NEXT: [[ZEXT_43:%.*]] = sext i1 [[CMP_43]] to i32146; CHECK-NEXT: store i32 [[ZEXT_43]], ptr @G, align 4147; CHECK-NEXT: [[CMP_44:%.*]] = icmp eq i32 0, [[LIMIT]]148; CHECK-NEXT: [[ZEXT_44:%.*]] = sext i1 [[CMP_44]] to i32149; CHECK-NEXT: store i32 [[ZEXT_44]], ptr @G, align 4150; CHECK-NEXT: [[CMP_45:%.*]] = icmp eq i32 0, [[LIMIT]]151; CHECK-NEXT: [[ZEXT_45:%.*]] = sext i1 [[CMP_45]] to i32152; CHECK-NEXT: store i32 [[ZEXT_45]], ptr @G, align 4153; CHECK-NEXT: [[CMP_46:%.*]] = icmp eq i32 0, [[LIMIT]]154; CHECK-NEXT: [[ZEXT_46:%.*]] = sext i1 [[CMP_46]] to i32155; CHECK-NEXT: store i32 [[ZEXT_46]], ptr @G, align 4156; CHECK-NEXT: [[CMP_47:%.*]] = icmp eq i32 0, [[LIMIT]]157; CHECK-NEXT: [[ZEXT_47:%.*]] = sext i1 [[CMP_47]] to i32158; CHECK-NEXT: store i32 [[ZEXT_47]], ptr @G, align 4159; CHECK-NEXT: [[CMP_48:%.*]] = icmp eq i32 0, [[LIMIT]]160; CHECK-NEXT: [[ZEXT_48:%.*]] = sext i1 [[CMP_48]] to i32161; CHECK-NEXT: store i32 [[ZEXT_48]], ptr @G, align 4162; CHECK-NEXT: [[CMP_49:%.*]] = icmp eq i32 0, [[LIMIT]]163; CHECK-NEXT: [[ZEXT_49:%.*]] = sext i1 [[CMP_49]] to i32164; CHECK-NEXT: store i32 [[ZEXT_49]], ptr @G, align 4165; CHECK-NEXT: [[CMP_50:%.*]] = icmp eq i32 0, [[LIMIT]]166; CHECK-NEXT: [[ZEXT_50:%.*]] = sext i1 [[CMP_50]] to i32167; CHECK-NEXT: store i32 [[ZEXT_50]], ptr @G, align 4168; CHECK-NEXT: [[CMP_51:%.*]] = icmp eq i32 0, [[LIMIT]]169; CHECK-NEXT: [[ZEXT_51:%.*]] = sext i1 [[CMP_51]] to i32170; CHECK-NEXT: store i32 [[ZEXT_51]], ptr @G, align 4171; CHECK-NEXT: [[CMP_52:%.*]] = icmp eq i32 0, [[LIMIT]]172; CHECK-NEXT: [[ZEXT_52:%.*]] = sext i1 [[CMP_52]] to i32173; CHECK-NEXT: store i32 [[ZEXT_52]], ptr @G, align 4174; CHECK-NEXT: [[CMP_53:%.*]] = icmp eq i32 0, [[LIMIT]]175; CHECK-NEXT: [[ZEXT_53:%.*]] = sext i1 [[CMP_53]] to i32176; CHECK-NEXT: store i32 [[ZEXT_53]], ptr @G, align 4177; CHECK-NEXT: [[CMP_54:%.*]] = icmp eq i32 0, [[LIMIT]]178; CHECK-NEXT: [[ZEXT_54:%.*]] = sext i1 [[CMP_54]] to i32179; CHECK-NEXT: store i32 [[ZEXT_54]], ptr @G, align 4180; CHECK-NEXT: [[CMP_55:%.*]] = icmp eq i32 0, [[LIMIT]]181; CHECK-NEXT: [[ZEXT_55:%.*]] = sext i1 [[CMP_55]] to i32182; CHECK-NEXT: store i32 [[ZEXT_55]], ptr @G, align 4183; CHECK-NEXT: [[CMP_56:%.*]] = icmp eq i32 0, [[LIMIT]]184; CHECK-NEXT: [[ZEXT_56:%.*]] = sext i1 [[CMP_56]] to i32185; CHECK-NEXT: store i32 [[ZEXT_56]], ptr @G, align 4186; CHECK-NEXT: [[CMP_57:%.*]] = icmp eq i32 0, [[LIMIT]]187; CHECK-NEXT: [[ZEXT_57:%.*]] = sext i1 [[CMP_57]] to i32188; CHECK-NEXT: store i32 [[ZEXT_57]], ptr @G, align 4189; CHECK-NEXT: [[CMP_58:%.*]] = icmp eq i32 0, [[LIMIT]]190; CHECK-NEXT: [[ZEXT_58:%.*]] = sext i1 [[CMP_58]] to i32191; CHECK-NEXT: store i32 [[ZEXT_58]], ptr @G, align 4192; CHECK-NEXT: [[CMP_59:%.*]] = icmp eq i32 0, [[LIMIT]]193; CHECK-NEXT: [[ZEXT_59:%.*]] = sext i1 [[CMP_59]] to i32194; CHECK-NEXT: store i32 [[ZEXT_59]], ptr @G, align 4195; CHECK-NEXT: [[CMP_60:%.*]] = icmp eq i32 0, [[LIMIT]]196; CHECK-NEXT: [[ZEXT_60:%.*]] = sext i1 [[CMP_60]] to i32197; CHECK-NEXT: store i32 [[ZEXT_60]], ptr @G, align 4198; CHECK-NEXT: [[CMP_61:%.*]] = icmp eq i32 0, [[LIMIT]]199; CHECK-NEXT: [[ZEXT_61:%.*]] = sext i1 [[CMP_61]] to i32200; CHECK-NEXT: store i32 [[ZEXT_61]], ptr @G, align 4201; CHECK-NEXT: [[CMP_62:%.*]] = icmp eq i32 0, [[LIMIT]]202; CHECK-NEXT: [[ZEXT_62:%.*]] = sext i1 [[CMP_62]] to i32203; CHECK-NEXT: store i32 [[ZEXT_62]], ptr @G, align 4204; CHECK-NEXT: [[CMP_63:%.*]] = icmp eq i32 0, [[LIMIT]]205; CHECK-NEXT: [[ZEXT_63:%.*]] = sext i1 [[CMP_63]] to i32206; CHECK-NEXT: store i32 [[ZEXT_63]], ptr @G, align 4207; CHECK-NEXT: [[CMP_64:%.*]] = icmp eq i32 0, [[LIMIT]]208; CHECK-NEXT: [[ZEXT_64:%.*]] = sext i1 [[CMP_64]] to i32209; CHECK-NEXT: store i32 [[ZEXT_64]], ptr @G, align 4210; CHECK-NEXT: [[CMP_65:%.*]] = icmp eq i32 0, [[LIMIT]]211; CHECK-NEXT: [[ZEXT_65:%.*]] = sext i1 [[CMP_65]] to i32212; CHECK-NEXT: store i32 [[ZEXT_65]], ptr @G, align 4213; CHECK-NEXT: [[CMP_66:%.*]] = icmp eq i32 0, [[LIMIT]]214; CHECK-NEXT: [[ZEXT_66:%.*]] = sext i1 [[CMP_66]] to i32215; CHECK-NEXT: store i32 [[ZEXT_66]], ptr @G, align 4216; CHECK-NEXT: [[CMP_67:%.*]] = icmp eq i32 0, [[LIMIT]]217; CHECK-NEXT: [[ZEXT_67:%.*]] = sext i1 [[CMP_67]] to i32218; CHECK-NEXT: store i32 [[ZEXT_67]], ptr @G, align 4219; CHECK-NEXT: [[CMP_68:%.*]] = icmp eq i32 0, [[LIMIT]]220; CHECK-NEXT: [[ZEXT_68:%.*]] = sext i1 [[CMP_68]] to i32221; CHECK-NEXT: store i32 [[ZEXT_68]], ptr @G, align 4222; CHECK-NEXT: [[CMP_69:%.*]] = icmp eq i32 0, [[LIMIT]]223; CHECK-NEXT: [[ZEXT_69:%.*]] = sext i1 [[CMP_69]] to i32224; CHECK-NEXT: store i32 [[ZEXT_69]], ptr @G, align 4225; CHECK-NEXT: [[CMP_70:%.*]] = icmp eq i32 0, [[LIMIT]]226; CHECK-NEXT: [[ZEXT_70:%.*]] = sext i1 [[CMP_70]] to i32227; CHECK-NEXT: store i32 [[ZEXT_70]], ptr @G, align 4228; CHECK-NEXT: [[CMP_71:%.*]] = icmp eq i32 0, [[LIMIT]]229; CHECK-NEXT: [[ZEXT_71:%.*]] = sext i1 [[CMP_71]] to i32230; CHECK-NEXT: store i32 [[ZEXT_71]], ptr @G, align 4231; CHECK-NEXT: [[CMP_72:%.*]] = icmp eq i32 0, [[LIMIT]]232; CHECK-NEXT: [[ZEXT_72:%.*]] = sext i1 [[CMP_72]] to i32233; CHECK-NEXT: store i32 [[ZEXT_72]], ptr @G, align 4234; CHECK-NEXT: [[CMP_73:%.*]] = icmp eq i32 0, [[LIMIT]]235; CHECK-NEXT: [[ZEXT_73:%.*]] = sext i1 [[CMP_73]] to i32236; CHECK-NEXT: store i32 [[ZEXT_73]], ptr @G, align 4237; CHECK-NEXT: [[CMP_74:%.*]] = icmp eq i32 0, [[LIMIT]]238; CHECK-NEXT: [[ZEXT_74:%.*]] = sext i1 [[CMP_74]] to i32239; CHECK-NEXT: store i32 [[ZEXT_74]], ptr @G, align 4240; CHECK-NEXT: [[CMP_75:%.*]] = icmp eq i32 0, [[LIMIT]]241; CHECK-NEXT: [[ZEXT_75:%.*]] = sext i1 [[CMP_75]] to i32242; CHECK-NEXT: store i32 [[ZEXT_75]], ptr @G, align 4243; CHECK-NEXT: [[CMP_76:%.*]] = icmp eq i32 0, [[LIMIT]]244; CHECK-NEXT: [[ZEXT_76:%.*]] = sext i1 [[CMP_76]] to i32245; CHECK-NEXT: store i32 [[ZEXT_76]], ptr @G, align 4246; CHECK-NEXT: [[CMP_77:%.*]] = icmp eq i32 0, [[LIMIT]]247; CHECK-NEXT: [[ZEXT_77:%.*]] = sext i1 [[CMP_77]] to i32248; CHECK-NEXT: store i32 [[ZEXT_77]], ptr @G, align 4249; CHECK-NEXT: [[CMP_78:%.*]] = icmp eq i32 0, [[LIMIT]]250; CHECK-NEXT: [[ZEXT_78:%.*]] = sext i1 [[CMP_78]] to i32251; CHECK-NEXT: store i32 [[ZEXT_78]], ptr @G, align 4252; CHECK-NEXT: [[CMP_79:%.*]] = icmp eq i32 0, [[LIMIT]]253; CHECK-NEXT: [[ZEXT_79:%.*]] = sext i1 [[CMP_79]] to i32254; CHECK-NEXT: store i32 [[ZEXT_79]], ptr @G, align 4255; CHECK-NEXT: [[CMP_80:%.*]] = icmp eq i32 0, [[LIMIT]]256; CHECK-NEXT: [[ZEXT_80:%.*]] = sext i1 [[CMP_80]] to i32257; CHECK-NEXT: store i32 [[ZEXT_80]], ptr @G, align 4258; CHECK-NEXT: ret i32 [[ZEXT_80]]259;260entry:261 br label %loop262 263loop: ; preds = %backedge, %entry264 %phi = phi i32 [ 0, %entry ], [ %limit, %loop ]265 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]266 %sub = sub i32 %limit, %phi267 %cmp = icmp eq i32 %sub, %limit268 %zext = sext i1 %cmp to i32269 store i32 %zext, ptr @G270 %iv.next = add i32 %iv, 1271 %loop.cond = icmp ne i32 %iv, 80272 br i1 %loop.cond, label %loop, label %done273 274done: ; preds = %backedge275 ret i32 %zext276}277 278; Use symbolic value facts to prune unreachable (expensive) paths279; 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 0448;449entry:450 br label %loop451 452loop: ; preds = %backedge, %entry453 %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ]454 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]455 %sub = sub i32 %limit, %sum456 %is.positive = icmp eq i32 %sub, %limit457 br i1 %is.positive, label %backedge, label %if.false458 459if.false: ; preds = %loop460 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 %backedge475 476backedge: ; preds = %if.false, %loop477 %hidden_zero = sub i32 %limit, %sub478 %sum.next = add i32 %sum, %hidden_zero479 %iv.next = add i32 %iv, 1480 %loop.cond = icmp ne i32 %iv, 8481 br i1 %loop.cond, label %loop, label %done482 483done: ; preds = %backedge484 %sum.next.lcssa = phi i32 [ %sum.next, %backedge ]485 ret i32 %sum.next.lcssa486}487 488; A test to show the ability to simplify branches (even without general489; 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:%.*]], 0494; 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]], 1522; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 8523; 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: unreachable529;530entry:531 %loop_guard = icmp sge i32 %limit, 0532 br i1 %loop_guard, label %loop, label %failure533 534loop: ; preds = %backedge, %entry535 %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ]536 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]537 %sub = sub i32 0, %sum538 %is.positive = icmp sle i32 %sub, %limit539 br i1 %is.positive, label %backedge, label %if.false540 541if.false: ; preds = %loop542 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 %backedge557 558backedge: ; preds = %if.false, %loop559 %sum.next = add i32 %sum, %sub560 %iv.next = add i32 %iv, 1561 %loop.cond = icmp ne i32 %iv, 8562 br i1 %loop.cond, label %loop, label %done563 564done: ; preds = %backedge565 %sum.next.lcssa = phi i32 [ %sum.next, %backedge ]566 ret i32 %sum.next.lcssa567 568failure:569 unreachable570}571 572; We can symbolically evaluate %sub to %limit on first iteration, and573; 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:%.*]], 0578; 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]], 0586; 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]], 1606; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 8607; 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: unreachable613;614entry:615 %loop_guard = icmp sge i32 %limit, 0616 br i1 %loop_guard, label %loop, label %failure617 618loop: ; preds = %backedge, %entry619 %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ]620 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]621 %sub = sub i32 %limit, %sum622 %is.positive = icmp sge i32 %sub, 0623 br i1 %is.positive, label %backedge, label %if.false624 625if.false: ; preds = %loop626 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 %backedge641 642backedge: ; preds = %if.false, %loop643 %sum.next = add i32 %sum, %sub644 %iv.next = add i32 %iv, 1645 %loop.cond = icmp ne i32 %iv, 8646 br i1 %loop.cond, label %loop, label %done647 648done: ; preds = %backedge649 %sum.next.lcssa = phi i32 [ %sum.next, %backedge ]650 ret i32 %sum.next.lcssa651 652failure:653 unreachable654}655 656declare void @foo()657