331 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=early-cse -earlycse-debug-hash -S < %s | FileCheck %s3; RUN: opt -passes='early-cse<memssa>' -S < %s | FileCheck %s4 5; Most basic case, fully identical PHI nodes6define void @test0(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {7; CHECK-LABEL: @test0(8; CHECK-NEXT: entry:9; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]10; CHECK: b0:11; CHECK-NEXT: br label [[END:%.*]]12; CHECK: b1:13; CHECK-NEXT: br label [[END]]14; CHECK: end:15; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]16; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]17; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 418; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 419; CHECK-NEXT: ret void20;21entry:22 br i1 %c, label %b0, label %b123 24b0:25 br label %end26 27b1:28 br label %end29 30end:31 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]32 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]33 store i32 %i0, ptr %d034 store i32 %i1, ptr %d135 ret void36}37 38; Fully identical PHI nodes, but order of operands differs39define void @test1(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {40; CHECK-LABEL: @test1(41; CHECK-NEXT: entry:42; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]43; CHECK: b0:44; CHECK-NEXT: br label [[END:%.*]]45; CHECK: b1:46; CHECK-NEXT: br label [[END]]47; CHECK: end:48; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]49; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [ [[V0]], [[B0]] ]50; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 451; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 452; CHECK-NEXT: ret void53;54entry:55 br i1 %c, label %b0, label %b156 57b0:58 br label %end59 60b1:61 br label %end62 63end:64 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]65 %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ]66 store i32 %i0, ptr %d067 store i32 %i1, ptr %d168 ret void69}70 71; Different incoming values in second PHI72define void @negative_test2(i32 %v0, i32 %v1, i32 %v2, i1 %c, ptr %d0, ptr %d1) {73; CHECK-LABEL: @negative_test2(74; CHECK-NEXT: entry:75; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]76; CHECK: b0:77; CHECK-NEXT: br label [[END:%.*]]78; CHECK: b1:79; CHECK-NEXT: br label [[END]]80; CHECK: end:81; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]82; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V2:%.*]], [[B1]] ]83; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 484; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 485; CHECK-NEXT: ret void86;87entry:88 br i1 %c, label %b0, label %b189 90b0:91 br label %end92 93b1:94 br label %end95 96end:97 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]98 %i1 = phi i32 [ %v0, %b0 ], [ %v2, %b1 ] ; from %b0 takes %v2 instead of %v199 store i32 %i0, ptr %d0100 store i32 %i1, ptr %d1101 ret void102}103define void @negative_test3(i32 %v0, i32 %v1, i32 %v2, i1 %c, ptr %d0, ptr %d1) {104; CHECK-LABEL: @negative_test3(105; CHECK-NEXT: entry:106; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]107; CHECK: b0:108; CHECK-NEXT: br label [[END:%.*]]109; CHECK: b1:110; CHECK-NEXT: br label [[END]]111; CHECK: end:112; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]113; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V2:%.*]], [[B1]] ], [ [[V0]], [[B0]] ]114; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4115; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4116; CHECK-NEXT: ret void117;118entry:119 br i1 %c, label %b0, label %b1120 121b0:122 br label %end123 124b1:125 br label %end126 127end:128 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]129 %i1 = phi i32 [ %v2, %b1 ], [ %v0, %b0 ] ; from %b0 takes %v2 instead of %v1130 store i32 %i0, ptr %d0131 store i32 %i1, ptr %d1132 ret void133}134define void @negative_test4(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {135; CHECK-LABEL: @negative_test4(136; CHECK-NEXT: entry:137; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]138; CHECK: b0:139; CHECK-NEXT: br label [[END:%.*]]140; CHECK: b1:141; CHECK-NEXT: br label [[END]]142; CHECK: end:143; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]144; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [ [[V0]], [[B0]] ]145; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4146; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4147; CHECK-NEXT: ret void148;149entry:150 br i1 %c, label %b0, label %b1151 152b0:153 br label %end154 155b1:156 br label %end157 158end:159 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]160 %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ] ; incoming values are swapped161 store i32 %i0, ptr %d0162 store i32 %i1, ptr %d1163 ret void164}165 166; Both PHI's are identical, but the first one has no uses, so ignore it.167define void @test5(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {168; CHECK-LABEL: @test5(169; CHECK-NEXT: entry:170; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]171; CHECK: b0:172; CHECK-NEXT: br label [[END:%.*]]173; CHECK: b1:174; CHECK-NEXT: br label [[END]]175; CHECK: end:176; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]177; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4178; CHECK-NEXT: ret void179;180entry:181 br i1 %c, label %b0, label %b1182 183b0:184 br label %end185 186b1:187 br label %end188 189end:190 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused191 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]192 store i32 %i1, ptr %d1193 ret void194}195; Second PHI has no uses196define void @test6(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {197; CHECK-LABEL: @test6(198; CHECK-NEXT: entry:199; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]200; CHECK: b0:201; CHECK-NEXT: br label [[END:%.*]]202; CHECK: b1:203; CHECK-NEXT: br label [[END]]204; CHECK: end:205; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]206; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4207; CHECK-NEXT: ret void208;209entry:210 br i1 %c, label %b0, label %b1211 212b0:213 br label %end214 215b1:216 br label %end217 218end:219 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]220 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused221 store i32 %i0, ptr %d0222 ret void223}224 225; Non-matching PHI node should be ignored without terminating CSE.226define void @test7(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {227; CHECK-LABEL: @test7(228; CHECK-NEXT: entry:229; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]230; CHECK: b0:231; CHECK-NEXT: br label [[END:%.*]]232; CHECK: b1:233; CHECK-NEXT: br label [[END]]234; CHECK: end:235; CHECK-NEXT: [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]236; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]237; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]238; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4239; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4240; CHECK-NEXT: store i16 [[IBAD]], ptr [[D2:%.*]], align 2241; CHECK-NEXT: ret void242;243entry:244 br i1 %c, label %b0, label %b1245 246b0:247 br label %end248 249b1:250 br label %end251 252end:253 %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]254 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]255 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]256 store i32 %i0, ptr %d0257 store i32 %i1, ptr %d1258 store i16 %iBAD, ptr %d2259 ret void260}261define void @test8(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {262; CHECK-LABEL: @test8(263; CHECK-NEXT: entry:264; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]265; CHECK: b0:266; CHECK-NEXT: br label [[END:%.*]]267; CHECK: b1:268; CHECK-NEXT: br label [[END]]269; CHECK: end:270; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]271; CHECK-NEXT: [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]272; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]273; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4274; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4275; CHECK-NEXT: store i16 [[IBAD]], ptr [[D2:%.*]], align 2276; CHECK-NEXT: ret void277;278entry:279 br i1 %c, label %b0, label %b1280 281b0:282 br label %end283 284b1:285 br label %end286 287end:288 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]289 %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]290 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]291 store i32 %i0, ptr %d0292 store i32 %i1, ptr %d1293 store i16 %iBAD, ptr %d2294 ret void295}296define void @test9(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {297; CHECK-LABEL: @test9(298; CHECK-NEXT: entry:299; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]300; CHECK: b0:301; CHECK-NEXT: br label [[END:%.*]]302; CHECK: b1:303; CHECK-NEXT: br label [[END]]304; CHECK: end:305; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]306; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]307; CHECK-NEXT: [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]308; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4309; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4310; CHECK-NEXT: store i16 [[IBAD]], ptr [[D2:%.*]], align 2311; CHECK-NEXT: ret void312;313entry:314 br i1 %c, label %b0, label %b1315 316b0:317 br label %end318 319b1:320 br label %end321 322end:323 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]324 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]325 %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]326 store i32 %i0, ptr %d0327 store i32 %i1, ptr %d1328 store i16 %iBAD, ptr %d2329 ret void330}331