660 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt %s -passes=sccp -S | FileCheck --check-prefixes=CHECK,SCCP %s3; RUN: opt %s -passes=ipsccp -S | FileCheck --check-prefixes=CHECK,IPSCCP %s4 5; Test different widening scenarios.6 7declare void @use(i1)8declare i1 @cond()9 10define void @test_2_incoming_constants(i32 %x) {11; CHECK-LABEL: @test_2_incoming_constants(12; CHECK-NEXT: entry:13; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()14; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]15; CHECK: bb1:16; CHECK-NEXT: br label [[EXIT]]17; CHECK: exit:18; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ]19; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 120; CHECK-NEXT: call void @use(i1 true)21; CHECK-NEXT: call void @use(i1 false)22; CHECK-NEXT: ret void23;24entry:25 %c.1 = call i1 @cond()26 br i1 %c.1, label %bb1, label %exit27 28bb1:29 br label %exit30 31exit:32 %p = phi i32 [0, %entry], [1, %bb1]33 %a = add i32 %p, 134 %t.1 = icmp ult i32 %a, 2035 call void @use(i1 %t.1)36 %f.1 = icmp ugt i32 %a, 1037 call void @use(i1 %f.1)38 ret void39}40 41define void @test_3_incoming_constants(i32 %x) {42; CHECK-LABEL: @test_3_incoming_constants(43; CHECK-NEXT: entry:44; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()45; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]46; CHECK: bb1:47; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()48; CHECK-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]49; CHECK: bb2:50; CHECK-NEXT: br label [[EXIT]]51; CHECK: exit:52; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ]53; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 154; CHECK-NEXT: call void @use(i1 true)55; CHECK-NEXT: call void @use(i1 false)56; CHECK-NEXT: ret void57;58entry:59 %c.1 = call i1 @cond()60 br i1 %c.1, label %bb1, label %exit61 62bb1:63 %c.2 = call i1 @cond()64 br i1 %c.2, label %bb2, label %exit65 66bb2:67 br label %exit68 69exit:70 %p = phi i32 [0, %entry], [1, %bb1], [2, %bb2]71 %a = add i32 %p, 172 %t.1 = icmp ult i32 %a, 2073 call void @use(i1 %t.1)74 %f.1 = icmp ugt i32 %a, 1075 call void @use(i1 %f.1)76 ret void77}78 79define void @test_5_incoming_constants(i32 %x) {80; CHECK-LABEL: @test_5_incoming_constants(81; CHECK-NEXT: entry:82; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()83; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]84; CHECK: bb1:85; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()86; CHECK-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]87; CHECK: bb2:88; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()89; CHECK-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]90; CHECK: bb3:91; CHECK-NEXT: [[C_4:%.*]] = call i1 @cond()92; CHECK-NEXT: br i1 [[C_4]], label [[BB4:%.*]], label [[EXIT]]93; CHECK: bb4:94; CHECK-NEXT: br label [[EXIT]]95; CHECK: exit:96; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ]97; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 198; CHECK-NEXT: call void @use(i1 true)99; CHECK-NEXT: call void @use(i1 false)100; CHECK-NEXT: ret void101;102entry:103 %c.1 = call i1 @cond()104 br i1 %c.1, label %bb1, label %exit105 106bb1:107 %c.2 = call i1 @cond()108 br i1 %c.2, label %bb2, label %exit109 110bb2:111 %c.3 = call i1 @cond()112 br i1 %c.3, label %bb3, label %exit113 114bb3:115 %c.4 = call i1 @cond()116 br i1 %c.4, label %bb4, label %exit117 118bb4:119 br label %exit120 121exit:122 %p = phi i32 [0, %entry], [1, %bb1], [2, %bb2], [3, %bb3], [4, %bb4]123 %a = add i32 %p, 1124 %t.1 = icmp ult i32 %a, 20125 call void @use(i1 %t.1)126 %f.1 = icmp ugt i32 %a, 10127 call void @use(i1 %f.1)128 ret void129}130 131; For the rotated_loop_* test cases %p and %a are extended on each iteration.132 133define void @rotated_loop_2(i32 %x) {134; CHECK-LABEL: @rotated_loop_2(135; CHECK-NEXT: entry:136; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()137; CHECK-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]138; CHECK: bb1:139; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()140; CHECK-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]141; CHECK: bb2:142; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()143; CHECK-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]144; CHECK: bb3:145; CHECK-NEXT: br label [[EXIT]]146; CHECK: exit:147; CHECK-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ]148; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 1149; CHECK-NEXT: call void @use(i1 true)150; CHECK-NEXT: call void @use(i1 false)151; CHECK-NEXT: br label [[EXIT_1:%.*]]152; CHECK: exit.1:153; CHECK-NEXT: ret void154;155entry:156 %c.1 = call i1 @cond()157 br i1 %c.1, label %exit, label %bb1158 159bb1:160 %c.2 = call i1 @cond()161 br i1 %c.2, label %exit, label %bb2162 163bb2:164 %c.3 = call i1 @cond()165 br i1 %c.3, label %bb3, label %exit166 167bb3:168 br label %exit169 170exit:171 %p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit]172 %a = add i32 %p, 1173 %t.1 = icmp ult i32 %a, 20174 call void @use(i1 %t.1)175 %f.1 = icmp ugt i32 %a, 10176 call void @use(i1 %f.1)177 %c.4 = icmp ult i32 %a, 2178 br i1 %c.4, label %exit, label %exit.1179 180exit.1:181 ret void182}183 184define void @rotated_loop_3(i32 %x) {185; CHECK-LABEL: @rotated_loop_3(186; CHECK-NEXT: entry:187; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()188; CHECK-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]189; CHECK: bb1:190; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()191; CHECK-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]192; CHECK: bb2:193; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()194; CHECK-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]195; CHECK: bb3:196; CHECK-NEXT: br label [[EXIT]]197; CHECK: exit:198; CHECK-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ]199; CHECK-NEXT: [[A]] = add i32 [[P]], 1200; CHECK-NEXT: [[T_1:%.*]] = icmp ult i32 [[A]], 20201; CHECK-NEXT: call void @use(i1 [[T_1]])202; CHECK-NEXT: [[F_1:%.*]] = icmp ugt i32 [[A]], 10203; CHECK-NEXT: call void @use(i1 [[F_1]])204; CHECK-NEXT: [[C_4:%.*]] = icmp ult i32 [[A]], 3205; CHECK-NEXT: br i1 [[C_4]], label [[EXIT]], label [[EXIT_1:%.*]]206; CHECK: exit.1:207; CHECK-NEXT: ret void208;209entry:210 %c.1 = call i1 @cond()211 br i1 %c.1, label %exit, label %bb1212 213bb1:214 %c.2 = call i1 @cond()215 br i1 %c.2, label %exit, label %bb2216 217bb2:218 %c.3 = call i1 @cond()219 br i1 %c.3, label %bb3, label %exit220 221bb3:222 br label %exit223 224exit:225 %p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit]226 %a = add i32 %p, 1227 %t.1 = icmp ult i32 %a, 20228 call void @use(i1 %t.1)229 %f.1 = icmp ugt i32 %a, 10230 call void @use(i1 %f.1)231 %c.4 = icmp ult i32 %a, 3232 br i1 %c.4, label %exit, label %exit.1233 234exit.1:235 ret void236}237 238; For the loop_with_header_* tests, %iv and %a change on each iteration, but we239; can use the range imposed by the condition %c.1 when widening.240define void @loop_with_header_1(i32 %x) {241; CHECK-LABEL: @loop_with_header_1(242; CHECK-NEXT: entry:243; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]244; CHECK: loop.header:245; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]246; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 2247; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]248; CHECK: loop.body:249; CHECK-NEXT: call void @use(i1 true)250; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1251; CHECK-NEXT: br label [[LOOP_HEADER]]252; CHECK: exit:253; CHECK-NEXT: ret void254;255entry:256 br label %loop.header257 258loop.header:259 %iv = phi i32 [0, %entry], [%iv.next, %loop.body]260 %c.1 = icmp slt i32 %iv, 2261 br i1 %c.1, label %loop.body, label %exit262 263loop.body:264 %t.1 = icmp slt i32 %iv, 2265 call void @use(i1 %t.1)266 %iv.next = add nsw i32 %iv, 1267 br label %loop.header268 269exit:270 ret void271}272 273define void @loop_with_header_2(i32 %x) {274; CHECK-LABEL: @loop_with_header_2(275; CHECK-NEXT: entry:276; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]277; CHECK: loop.header:278; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]279; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 200280; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]281; CHECK: loop.body:282; CHECK-NEXT: call void @use(i1 true)283; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1284; CHECK-NEXT: br label [[LOOP_HEADER]]285; CHECK: exit:286; CHECK-NEXT: ret void287;288entry:289 br label %loop.header290 291loop.header:292 %iv = phi i32 [0, %entry], [%iv.next, %loop.body]293 %c.1 = icmp slt i32 %iv, 200294 br i1 %c.1, label %loop.body, label %exit295 296loop.body:297 %t.1 = icmp slt i32 %iv, 200298 call void @use(i1 %t.1)299 %iv.next = add nsw i32 %iv, 1300 br label %loop.header301 302exit:303 ret void304}305 306; In the function below, the condition %c.1 results in a range [7, 6), which307; can be used as a widening bound. It does not fully contain the range we get308; from combining it with the information from %tmp12.309define void @foo(ptr %arg, i8 %x) {310; CHECK-LABEL: @foo(311; CHECK-NEXT: bb:312; CHECK-NEXT: [[TMP:%.*]] = zext i8 [[X:%.*]] to i32313; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 8314; CHECK-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [315; CHECK-NEXT: i32 1, label [[BB3:%.*]]316; CHECK-NEXT: i32 2, label [[BB4:%.*]]317; CHECK-NEXT: i32 4, label [[BB19:%.*]]318; CHECK-NEXT: ]319; CHECK: bb3:320; CHECK-NEXT: unreachable321; CHECK: bb4:322; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3323; CHECK-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3324; CHECK-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]]325; CHECK-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1326; CHECK-NEXT: [[TMP9:%.*]] = trunc nuw nsw i64 [[TMP8]] to i32327; CHECK-NEXT: [[TMP10:%.*]] = zext nneg i32 [[TMP9]] to i64328; CHECK-NEXT: br label [[BB11:%.*]]329; CHECK: bb11:330; CHECK-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP10]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]331; CHECK-NEXT: br label [[BB13:%.*]]332; CHECK: bb13:333; CHECK-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6334; CHECK-NEXT: br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]]335; CHECK: bb15:336; CHECK-NEXT: unreachable337; CHECK: bb16:338; CHECK-NEXT: [[TMP17]] = add i64 [[TMP12]], 2339; CHECK-NEXT: br label [[BB18]]340; CHECK: bb18:341; CHECK-NEXT: br label [[BB11]]342; CHECK: bb19:343; CHECK-NEXT: unreachable344; CHECK: bb20:345; CHECK-NEXT: ret void346;347bb:348 %tmp = zext i8 %x to i32349 %tmp2 = load i64, ptr %arg, align 8350 switch i32 %tmp, label %bb20 [351 i32 1, label %bb3352 i32 2, label %bb4353 i32 4, label %bb19354 ]355 356bb3: ; preds = %bb357 unreachable358 359bb4: ; preds = %bb360 %tmp5 = add i64 %tmp2, 3361 %tmp6 = and i64 %tmp5, 3362 %tmp7 = sub i64 3, %tmp6363 %tmp8 = shl i64 %tmp7, 1364 %tmp9 = trunc i64 %tmp8 to i32365 %tmp10 = sext i32 %tmp9 to i64366 br label %bb11367 368bb11: ; preds = %bb18, %bb4369 %tmp12 = phi i64 [ %tmp10, %bb4 ], [ %tmp17, %bb18 ]370 br label %bb13371 372bb13: ; preds = %bb11373 %c.1 = icmp eq i64 %tmp12, 6374 br i1 %c.1, label %bb15, label %bb16375 376bb15: ; preds = %bb13377 unreachable378 379bb16: ; preds = %bb13380 %tmp17 = add i64 %tmp12, 2381 br label %bb18382 383bb18: ; preds = %bb16384 br label %bb11385 386bb19: ; preds = %bb387 unreachable388 389bb20: ; preds = %bb390 ret void391}392 393; The functions below check that widening with an upper bound does correctly394; return whether the range changed. Make sure we do not eliminate %c.2.395 396%struct.baz.1 = type { i32, i32, ptr, ptr }397%struct.blam.2 = type <{ %struct.baz.1, i32, [4 x i8] }>398 399@global.11 = linkonce_odr global [4 x i8] zeroinitializer, align 1400 401declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1402 403define linkonce_odr dereferenceable(1) ptr @spam(ptr %arg, i32 %arg1) align 2 {404; CHECK-LABEL: @spam(405; CHECK-NEXT: bb:406; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds nuw [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3407; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8408; CHECK-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64409; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 [[TMP3]]410; CHECK-NEXT: ret ptr [[TMP4]]411;412bb:413 %tmp = getelementptr inbounds %struct.baz.1, ptr %arg, i32 0, i32 3414 %tmp2 = load ptr, ptr %tmp, align 8415 %tmp3 = sext i32 %arg1 to i64416 %tmp4 = getelementptr inbounds i8, ptr %tmp2, i64 %tmp3417 ret ptr %tmp4418}419 420define ptr @wobble(ptr %arg, i32 %arg1) align 2 {421; CHECK-LABEL: @wobble(422; CHECK-NEXT: bb:423; CHECK-NEXT: [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16424; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]425; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535426; CHECK-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8427; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1428; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8429; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]430; CHECK-NEXT: br label [[BB8:%.*]]431; CHECK: bb8:432; CHECK-NEXT: [[TMP9:%.*]] = phi ptr [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ]433; CHECK-NEXT: [[TMP10:%.*]] = phi ptr [ undef, [[BB]] ], [ [[TMP17]], [[BB29]] ]434; CHECK-NEXT: [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ]435; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8436; CHECK-NEXT: br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]]437; CHECK: bb13:438; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]439; CHECK-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4440; CHECK-NEXT: [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]])441; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2442; CHECK-NEXT: [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1443; CHECK-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32444; CHECK-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0445; CHECK-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]446; CHECK: bb23:447; CHECK-NEXT: [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16448; CHECK-NEXT: store i16 [[TMP24]], ptr [[TMP17]], align 2449; CHECK-NEXT: br label [[BB31]]450; CHECK: bb25:451; CHECK-NEXT: [[TMP26:%.*]] = load i16, ptr [[TMP17]], align 2452; CHECK-NEXT: [[TMP27:%.*]] = zext i16 [[TMP26]] to i32453; CHECK-NEXT: [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]]454; CHECK-NEXT: br i1 [[TMP28]], label [[BB31]], label [[BB29]]455; CHECK: bb29:456; CHECK-NEXT: [[TMP30]] = add nsw i32 [[TMP11]], 1457; CHECK-NEXT: br label [[BB8]]458; CHECK: bb31:459; CHECK-NEXT: [[TMP32:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ]460; CHECK-NEXT: [[TMP33:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP10]], [[BB8]] ]461; CHECK-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0462; CHECK-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]463; CHECK: bb35:464; CHECK-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1465; CHECK-NEXT: br label [[BB66:%.*]]466; CHECK: bb37:467; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8468; CHECK-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]469; CHECK: bb39:470; CHECK-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16471; CHECK-NEXT: store i16 [[TMP41]], ptr @global.11, align 1472; CHECK-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], 7473; CHECK-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4474; CHECK-NEXT: [[TMP45:%.*]] = add i32 [[TMP44]], 2475; CHECK-NEXT: [[TMP46:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP45]])476; CHECK-NEXT: [[TMP47:%.*]] = load i8, ptr [[TMP46]], align 1477; CHECK-NEXT: [[TMP48:%.*]] = zext i8 [[TMP47]] to i32478; CHECK-NEXT: [[TMP49:%.*]] = sub i32 [[TMP43]], 1479; CHECK-NEXT: [[TMP50:%.*]] = mul i32 [[TMP49]], 4480; CHECK-NEXT: [[TMP51:%.*]] = add i32 [[TMP50]], 2481; CHECK-NEXT: [[TMP52:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP51]])482; CHECK-NEXT: [[TMP53:%.*]] = load i8, ptr [[TMP52]], align 1483; CHECK-NEXT: [[TMP54:%.*]] = zext i8 [[TMP53]] to i32484; CHECK-NEXT: [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]]485; CHECK-NEXT: br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]]486; CHECK: bb56:487; CHECK-NEXT: br label [[BB60]]488; CHECK: bb58:489; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 @global.11, ptr align 2 [[TMP33]], i64 4, i1 false)490; CHECK-NEXT: br label [[BB60]]491; CHECK: bb60:492; CHECK-NEXT: [[TMP61:%.*]] = phi i32 [ 6, [[BB56]] ], [ 7, [[BB39]] ], [ [[TMP11]], [[BB58]] ]493; CHECK-NEXT: [[TMP63:%.*]] = add i32 [[TMP7]], 1494; CHECK-NEXT: [[TMP64:%.*]] = mul i32 [[TMP63]], 4495; CHECK-NEXT: [[TMP65:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP64]])496; CHECK-NEXT: br label [[BB66]]497; CHECK: bb66:498; CHECK-NEXT: [[TMP67:%.*]] = phi ptr [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ]499; CHECK-NEXT: ret ptr [[TMP67]]500;501bb:502 %tmp = lshr i32 %arg1, 16503 %tmp2 = xor i32 %tmp, %arg1504 %tmp3 = and i32 %tmp2, 65535505 %tmp4 = mul i32 %arg1, 8506 %tmp5 = getelementptr inbounds %struct.blam.2, ptr %arg, i32 0, i32 1507 %tmp6 = load i32, ptr %tmp5, align 8508 %tmp7 = and i32 %tmp4, %tmp6509 br label %bb8510 511bb8: ; preds = %bb29, %bb512 %tmp9 = phi ptr [ undef, %bb ], [ %tmp17, %bb29 ]513 %tmp10 = phi ptr [ undef, %bb ], [ %tmp17, %bb29 ]514 %tmp11 = phi i32 [ 0, %bb ], [ %tmp30, %bb29 ]515 %c.1 = icmp slt i32 %tmp11, 8516 br i1 %c.1, label %bb13, label %bb31517 518bb13: ; preds = %bb8519 %tmp15 = add i32 %tmp7, %tmp11520 %tmp16 = mul i32 %tmp15, 4521 %tmp17 = call dereferenceable(1) ptr @spam(ptr %arg, i32 %tmp16)522 %tmp19 = getelementptr inbounds i8, ptr %tmp17, i64 2523 %tmp20 = load i8, ptr %tmp19, align 1524 %tmp21 = zext i8 %tmp20 to i32525 %tmp22 = icmp eq i32 %tmp21, 0526 br i1 %tmp22, label %bb23, label %bb25527 528bb23: ; preds = %bb13529 %tmp24 = trunc i32 %tmp3 to i16530 store i16 %tmp24, ptr %tmp17, align 2531 br label %bb31532 533bb25: ; preds = %bb13534 %tmp26 = load i16, ptr %tmp17, align 2535 %tmp27 = zext i16 %tmp26 to i32536 %tmp28 = icmp eq i32 %tmp27, %tmp3537 br i1 %tmp28, label %bb31, label %bb29538 539bb29: ; preds = %bb25540 %tmp30 = add nsw i32 %tmp11, 1541 br label %bb8542 543bb31: ; preds = %bb25, %bb23, %bb8544 %tmp32 = phi ptr [ %tmp17, %bb23 ], [ %tmp17, %bb25 ], [ %tmp9, %bb8 ]545 %tmp33 = phi ptr [ %tmp17, %bb23 ], [ %tmp17, %bb25 ], [ %tmp10, %bb8 ]546 %tmp34 = icmp eq i32 %tmp11, 0547 br i1 %tmp34, label %bb35, label %bb37548 549bb35: ; preds = %bb31550 %tmp36 = getelementptr inbounds i8, ptr %tmp32, i64 1551 br label %bb66552 553bb37: ; preds = %bb31554 %c.2 = icmp eq i32 %tmp11, 8555 br i1 %c.2, label %bb39, label %bb58556 557bb39: ; preds = %bb37558 %tmp40 = add nsw i32 %tmp11, -1559 %tmp41 = trunc i32 %tmp3 to i16560 store i16 %tmp41, ptr @global.11, align 1561 %tmp43 = add i32 %tmp7, %tmp40562 %tmp44 = mul i32 %tmp43, 4563 %tmp45 = add i32 %tmp44, 2564 %tmp46 = call dereferenceable(1) ptr @spam(ptr %arg, i32 %tmp45)565 %tmp47 = load i8, ptr %tmp46, align 1566 %tmp48 = zext i8 %tmp47 to i32567 %tmp49 = sub i32 %tmp43, 1568 %tmp50 = mul i32 %tmp49, 4569 %tmp51 = add i32 %tmp50, 2570 %tmp52 = call dereferenceable(1) ptr @spam(ptr %arg, i32 %tmp51)571 %tmp53 = load i8, ptr %tmp52, align 1572 %tmp54 = zext i8 %tmp53 to i32573 %tmp55 = icmp sgt i32 %tmp48, %tmp54574 br i1 %tmp55, label %bb56, label %bb60575 576bb56: ; preds = %bb39577 %tmp57 = add nsw i32 %tmp40, -1578 br label %bb60579 580bb58: ; preds = %bb37581 call void @llvm.memcpy.p0.p0.i64(ptr align 1 @global.11, ptr align 2 %tmp33, i64 4, i1 false)582 br label %bb60583 584bb60: ; preds = %bb58, %bb56, %bb39585 %tmp61 = phi i32 [ %tmp57, %bb56 ], [ %tmp40, %bb39 ], [ %tmp11, %bb58 ]586 %tmp63 = add i32 %tmp7, 1587 %tmp64 = mul i32 %tmp63, 4588 %tmp65 = call dereferenceable(1) ptr @spam(ptr %arg, i32 %tmp64)589 br label %bb66590 591bb66: ; preds = %bb60, %bb35592 %tmp67 = phi ptr [ %tmp36, %bb35 ], [ null, %bb60 ]593 ret ptr %tmp67594}595 596 597define i32 @loop_with_multiple_euqal_incomings(i32 %N) {598; CHECK-LABEL: @loop_with_multiple_euqal_incomings(599; CHECK-NEXT: entry:600; CHECK-NEXT: br label [[LOOP:%.*]]601; CHECK: loop:602; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[BB3:%.*]] ], [ 0, [[BB4:%.*]] ], [ 0, [[BB5:%.*]] ], [ 0, [[BB6:%.*]] ]603; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()604; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]605; CHECK: bb1:606; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()607; CHECK-NEXT: br i1 [[C_2]], label [[BB3]], label [[BB4]]608; CHECK: bb2:609; CHECK-NEXT: [[C_4:%.*]] = call i1 @cond()610; CHECK-NEXT: br i1 [[C_4]], label [[BB5]], label [[BB6]]611; CHECK: bb3:612; CHECK-NEXT: [[P_NEXT]] = add i32 [[P]], 1613; CHECK-NEXT: br label [[LOOP]]614; CHECK: bb4:615; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()616; CHECK-NEXT: br i1 [[C_3]], label [[LOOP]], label [[END:%.*]]617; CHECK: bb5:618; CHECK-NEXT: br label [[LOOP]]619; CHECK: bb6:620; CHECK-NEXT: br label [[LOOP]]621; CHECK: end:622; CHECK-NEXT: ret i32 [[P]]623;624entry:625 br label %loop626 627loop:628 %p = phi i32 [ 0, %entry ], [ %p.next, %bb3 ], [ 0, %bb4 ], [ 0, %bb5], [ 0, %bb6 ]629 %c.1 = call i1 @cond()630 br i1 %c.1, label %bb1, label %bb2631 632bb1:633 %c.2 = call i1 @cond()634 br i1 %c.2, label %bb3, label %bb4635 636bb2:637 %c.4 = call i1 @cond()638 br i1 %c.4, label %bb5, label %bb6639 640bb3:641 %p.next = add i32 %p, 1642 br label %loop643 644bb4:645 %c.3 = call i1 @cond()646 br i1 %c.3, label %loop, label %end647 648bb5:649 br label %loop650 651bb6:652 br label %loop653 654end:655 ret i32 %p656}657;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:658; IPSCCP: {{.*}}659; SCCP: {{.*}}660