324 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4; Most basic case, fully identical PHI nodes5define void @test0(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {6; CHECK-LABEL: @test0(7; CHECK-NEXT: entry:8; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]9; CHECK: b0:10; CHECK-NEXT: br label [[END:%.*]]11; CHECK: b1:12; CHECK-NEXT: br label [[END]]13; CHECK: end:14; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]15; CHECK-NEXT: store i32 [[I1]], ptr [[D0:%.*]], align 416; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 417; CHECK-NEXT: ret void18;19entry:20 br i1 %c, label %b0, label %b121 22b0:23 br label %end24 25b1:26 br label %end27 28end:29 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]30 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]31 store i32 %i0, ptr %d032 store i32 %i1, ptr %d133 ret void34}35 36; Fully identical PHI nodes, but order of operands differs37define void @test1(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {38; CHECK-LABEL: @test1(39; CHECK-NEXT: entry:40; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]41; CHECK: b0:42; CHECK-NEXT: br label [[END:%.*]]43; CHECK: b1:44; CHECK-NEXT: br label [[END]]45; CHECK: end:46; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]47; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 448; CHECK-NEXT: store i32 [[I0]], ptr [[D1:%.*]], align 449; CHECK-NEXT: ret void50;51entry:52 br i1 %c, label %b0, label %b153 54b0:55 br label %end56 57b1:58 br label %end59 60end:61 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]62 %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ]63 store i32 %i0, ptr %d064 store i32 %i1, ptr %d165 ret void66}67 68; Different incoming values in second PHI69define void @negative_test2(i32 %v0, i32 %v1, i32 %v2, i1 %c, ptr %d0, ptr %d1) {70; CHECK-LABEL: @negative_test2(71; CHECK-NEXT: entry:72; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]73; CHECK: b0:74; CHECK-NEXT: br label [[END:%.*]]75; CHECK: b1:76; CHECK-NEXT: br label [[END]]77; CHECK: end:78; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]79; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V2:%.*]], [[B1]] ]80; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 481; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 482; CHECK-NEXT: ret void83;84entry:85 br i1 %c, label %b0, label %b186 87b0:88 br label %end89 90b1:91 br label %end92 93end:94 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]95 %i1 = phi i32 [ %v0, %b0 ], [ %v2, %b1 ] ; from %b0 takes %v2 instead of %v196 store i32 %i0, ptr %d097 store i32 %i1, ptr %d198 ret void99}100define void @negative_test3(i32 %v0, i32 %v1, i32 %v2, i1 %c, ptr %d0, ptr %d1) {101; CHECK-LABEL: @negative_test3(102; CHECK-NEXT: entry:103; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]104; CHECK: b0:105; CHECK-NEXT: br label [[END:%.*]]106; CHECK: b1:107; CHECK-NEXT: br label [[END]]108; CHECK: end:109; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]110; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V2:%.*]], [[B1]] ]111; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4112; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4113; CHECK-NEXT: ret void114;115entry:116 br i1 %c, label %b0, label %b1117 118b0:119 br label %end120 121b1:122 br label %end123 124end:125 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]126 %i1 = phi i32 [ %v2, %b1 ], [ %v0, %b0 ] ; from %b0 takes %v2 instead of %v1127 store i32 %i0, ptr %d0128 store i32 %i1, ptr %d1129 ret void130}131define void @negative_test4(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {132; CHECK-LABEL: @negative_test4(133; CHECK-NEXT: entry:134; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]135; CHECK: b0:136; CHECK-NEXT: br label [[END:%.*]]137; CHECK: b1:138; CHECK-NEXT: br label [[END]]139; CHECK: end:140; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]141; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4142; CHECK-NEXT: store i32 [[I0]], ptr [[D1:%.*]], align 4143; CHECK-NEXT: ret void144;145entry:146 br i1 %c, label %b0, label %b1147 148b0:149 br label %end150 151b1:152 br label %end153 154end:155 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]156 %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ] ; incoming values are swapped157 store i32 %i0, ptr %d0158 store i32 %i1, ptr %d1159 ret void160}161 162; Both PHI's are identical, but the first one has no uses, so ignore it.163define void @test5(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {164; CHECK-LABEL: @test5(165; CHECK-NEXT: entry:166; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]167; CHECK: b0:168; CHECK-NEXT: br label [[END:%.*]]169; CHECK: b1:170; CHECK-NEXT: br label [[END]]171; CHECK: end:172; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]173; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4174; CHECK-NEXT: ret void175;176entry:177 br i1 %c, label %b0, label %b1178 179b0:180 br label %end181 182b1:183 br label %end184 185end:186 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused187 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]188 store i32 %i1, ptr %d1189 ret void190}191; Second PHI has no uses192define void @test6(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {193; CHECK-LABEL: @test6(194; CHECK-NEXT: entry:195; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]196; CHECK: b0:197; CHECK-NEXT: br label [[END:%.*]]198; CHECK: b1:199; CHECK-NEXT: br label [[END]]200; CHECK: end:201; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]202; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4203; CHECK-NEXT: ret void204;205entry:206 br i1 %c, label %b0, label %b1207 208b0:209 br label %end210 211b1:212 br label %end213 214end:215 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]216 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused217 store i32 %i0, ptr %d0218 ret void219}220 221; Non-matching PHI node should be ignored without terminating CSE.222define void @test7(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {223; CHECK-LABEL: @test7(224; CHECK-NEXT: entry:225; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]226; CHECK: b0:227; CHECK-NEXT: br label [[END:%.*]]228; CHECK: b1:229; CHECK-NEXT: br label [[END]]230; CHECK: end:231; CHECK-NEXT: [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]232; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]233; CHECK-NEXT: store i32 [[I1]], ptr [[D0:%.*]], align 4234; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4235; CHECK-NEXT: store i16 [[IBAD]], ptr [[D2:%.*]], align 2236; CHECK-NEXT: ret void237;238entry:239 br i1 %c, label %b0, label %b1240 241b0:242 br label %end243 244b1:245 br label %end246 247end:248 %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]249 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]250 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]251 store i32 %i0, ptr %d0252 store i32 %i1, ptr %d1253 store i16 %iBAD, ptr %d2254 ret void255}256define void @test8(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {257; CHECK-LABEL: @test8(258; CHECK-NEXT: entry:259; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]260; CHECK: b0:261; CHECK-NEXT: br label [[END:%.*]]262; CHECK: b1:263; CHECK-NEXT: br label [[END]]264; CHECK: end:265; CHECK-NEXT: [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]266; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]267; CHECK-NEXT: store i32 [[I1]], ptr [[D0:%.*]], align 4268; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4269; CHECK-NEXT: store i16 [[IBAD]], ptr [[D2:%.*]], align 2270; CHECK-NEXT: ret void271;272entry:273 br i1 %c, label %b0, label %b1274 275b0:276 br label %end277 278b1:279 br label %end280 281end:282 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]283 %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]284 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]285 store i32 %i0, ptr %d0286 store i32 %i1, ptr %d1287 store i16 %iBAD, ptr %d2288 ret void289}290define void @test9(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {291; CHECK-LABEL: @test9(292; CHECK-NEXT: entry:293; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]294; CHECK: b0:295; CHECK-NEXT: br label [[END:%.*]]296; CHECK: b1:297; CHECK-NEXT: br label [[END]]298; CHECK: end:299; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]300; CHECK-NEXT: [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]301; CHECK-NEXT: store i32 [[I1]], ptr [[D0:%.*]], align 4302; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4303; CHECK-NEXT: store i16 [[IBAD]], ptr [[D2:%.*]], align 2304; CHECK-NEXT: ret void305;306entry:307 br i1 %c, label %b0, label %b1308 309b0:310 br label %end311 312b1:313 br label %end314 315end:316 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]317 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]318 %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]319 store i32 %i0, ptr %d0320 store i32 %i1, ptr %d1321 store i16 %iBAD, ptr %d2322 ret void323}324