422 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=correlated-propagation %s | FileCheck %s3 4; Test case for PR44949.5 6declare void @use(i1)7 8; We can remove `%res = and i64 %p, 255`, because %r = 0 and we can eliminate9; %p as well.10define i64 @constant_and_undef(i1 %c1, i64 %a) {11; CHECK-LABEL: @constant_and_undef(12; CHECK-NEXT: entry:13; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]14; CHECK: bb1:15; CHECK-NEXT: br label [[BB3:%.*]]16; CHECK: bb2:17; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 018; CHECK-NEXT: br label [[BB3]]19; CHECK: bb3:20; CHECK-NEXT: call void @use(i1 false)21; CHECK-NEXT: call void @use(i1 true)22; CHECK-NEXT: ret i64 023;24entry:25 br i1 %c1, label %bb1, label %bb226 27bb1:28 br label %bb329 30bb2:31 %r = and i64 %a, 032 br label %bb333 34bb3:35 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]36 %res = and i64 %p, 25537 %f.1 = icmp eq i64 %p, 138 call void @use(i1 %f.1)39 %t.1 = icmp eq i64 %p, 040 call void @use(i1 %t.1)41 ret i64 %res42}43 44; Check that we go to overdefined when merging a constant range with undef. We45; cannot remove '%res = and i64 %p, 255'.46define i64 @constant_range_and_undef(i1 %cond, i64 %a) {47; CHECK-LABEL: @constant_range_and_undef(48; CHECK-NEXT: entry:49; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]50; CHECK: bb1:51; CHECK-NEXT: br label [[BB3:%.*]]52; CHECK: bb2:53; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 25554; CHECK-NEXT: br label [[BB3]]55; CHECK: bb3:56; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]57; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 25558; CHECK-NEXT: br label [[EXIT:%.*]]59; CHECK: exit:60; CHECK-NEXT: call void @use(i1 false)61; CHECK-NEXT: call void @use(i1 true)62; CHECK-NEXT: ret i64 [[RES]]63;64entry:65 br i1 %cond, label %bb1, label %bb266 67bb1:68 br label %bb369 70bb2:71 %r = and i64 %a, 25572 br label %bb373 74bb3:75 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]76 %res = and i64 %p, 25577 br label %exit78 79exit: ; CVP only simplifies based on ranges for non-local conditions.80 %f.1 = icmp eq i64 %p, 25681 call void @use(i1 %f.1)82 %t.1 = icmp ne i64 %p, 25683 call void @use(i1 %t.1)84 ret i64 %res85}86 87define i64 @constant_range_and_undef2(i1 %c1, i1 %c2, i64 %a) {88; CHECK-LABEL: @constant_range_and_undef2(89; CHECK-NEXT: entry:90; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]91; CHECK: bb1:92; CHECK-NEXT: [[V1:%.*]] = add i64 undef, undef93; CHECK-NEXT: br label [[BB3:%.*]]94; CHECK: bb2:95; CHECK-NEXT: [[V2:%.*]] = and i64 [[A:%.*]], 25596; CHECK-NEXT: br label [[BB3]]97; CHECK: bb3:98; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[V1]], [[BB1]] ], [ [[V2]], [[BB2]] ]99; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB4:%.*]], label [[BB5:%.*]]100; CHECK: bb4:101; CHECK-NEXT: br label [[BB6:%.*]]102; CHECK: bb5:103; CHECK-NEXT: [[V3:%.*]] = and i64 [[A]], 255104; CHECK-NEXT: br label [[BB6]]105; CHECK: bb6:106; CHECK-NEXT: [[P2:%.*]] = phi i64 [ [[P]], [[BB4]] ], [ [[V3]], [[BB5]] ]107; CHECK-NEXT: [[RES:%.*]] = and i64 [[P2]], 255108; CHECK-NEXT: br label [[EXIT:%.*]]109; CHECK: exit:110; CHECK-NEXT: [[F_1:%.*]] = icmp eq i64 [[P]], 256111; CHECK-NEXT: call void @use(i1 [[F_1]])112; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[P]], 256113; CHECK-NEXT: call void @use(i1 [[T_1]])114; CHECK-NEXT: ret i64 [[RES]]115;116entry:117 br i1 %c1, label %bb1, label %bb2118 119bb1:120 %v1 = add i64 undef, undef121 br label %bb3122 123bb2:124 %v2 = and i64 %a, 255125 br label %bb3126 127bb3:128 %p = phi i64 [ %v1, %bb1 ], [ %v2, %bb2 ]129 br i1 %c2, label %bb4, label %bb5130 131bb4:132 br label %bb6133 134bb5:135 %v3 = and i64 %a, 255136 br label %bb6137 138bb6:139 %p2 = phi i64 [ %p, %bb4 ], [ %v3, %bb5 ]140 %res = and i64 %p2, 255141 br label %exit142 143exit: ; CVP only simplifies based on ranges for non-local conditions.144 %f.1 = icmp eq i64 %p, 256145 call void @use(i1 %f.1)146 %t.1 = icmp ne i64 %p, 256147 call void @use(i1 %t.1)148 ret i64 %res149}150 151define i1 @constant_range_and_undef_3(i1 %cond, i64 %a) {152; CHECK-LABEL: @constant_range_and_undef_3(153; CHECK-NEXT: entry:154; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]155; CHECK: bb1:156; CHECK-NEXT: br label [[BB3:%.*]]157; CHECK: bb2:158; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255159; CHECK-NEXT: br label [[BB3]]160; CHECK: bb3:161; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]162; CHECK-NEXT: br label [[EXIT:%.*]]163; CHECK: exit:164; CHECK-NEXT: call void @use(i1 false)165; CHECK-NEXT: call void @use(i1 true)166; CHECK-NEXT: ret i1 true167;168entry:169 br i1 %cond, label %bb1, label %bb2170 171bb1:172 br label %bb3173 174bb2:175 %r = and i64 %a, 255176 br label %bb3177 178bb3:179 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]180 br label %exit181 182exit: ; CVP only simplifies based on ranges for non-local conditions.183 %c = icmp ult i64 %p, 256184 %f.1 = icmp eq i64 %p, 256185 call void @use(i1 %f.1)186 %t.1 = icmp ne i64 %p, 256187 call void @use(i1 %t.1)188 ret i1 %c189}190 191; Same as @constant_range_and_undef, but with 3 incoming192; values: undef, a constant and a constant range.193define i64 @constant_range_and_undef_3_incoming_v1(i1 %c1, i1 %c2, i64 %a) {194; CHECK-LABEL: @constant_range_and_undef_3_incoming_v1(195; CHECK-NEXT: entry:196; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]197; CHECK: bb1:198; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255199; CHECK-NEXT: br label [[BB4:%.*]]200; CHECK: bb2:201; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]202; CHECK: bb3:203; CHECK-NEXT: br label [[BB4]]204; CHECK: bb4:205; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB2]] ], [ undef, [[BB3]] ]206; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255207; CHECK-NEXT: br label [[EXIT:%.*]]208; CHECK: exit:209; CHECK-NEXT: call void @use(i1 false)210; CHECK-NEXT: call void @use(i1 true)211; CHECK-NEXT: ret i64 [[RES]]212;213entry:214 br i1 %c1, label %bb1, label %bb2215 216bb1:217 %r = and i64 %a, 255218 br label %bb4219 220bb2:221 br i1 %c2, label %bb3, label %bb4222 223bb3:224 br label %bb4225 226bb4:227 %p = phi i64 [ %r, %bb1 ], [ 10, %bb2], [ undef, %bb3 ]228 %res = and i64 %p, 255229 br label %exit230 231exit: ; CVP only simplifies based on ranges for non-local conditions.232 %f.1 = icmp eq i64 %p, 256233 call void @use(i1 %f.1)234 %t.1 = icmp ne i64 %p, 256235 call void @use(i1 %t.1)236 ret i64 %res237}238 239; Same as @constant_range_and_undef_3_incoming_v1, but with different order of240; incoming values.241define i64 @constant_range_and_undef_3_incoming_v2(i1 %c1, i1 %c2, i64 %a) {242; CHECK-LABEL: @constant_range_and_undef_3_incoming_v2(243; CHECK-NEXT: entry:244; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]245; CHECK: bb1:246; CHECK-NEXT: br label [[BB4:%.*]]247; CHECK: bb2:248; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]249; CHECK: bb3:250; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255251; CHECK-NEXT: br label [[BB4]]252; CHECK: bb4:253; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ 10, [[BB2]] ], [ [[R]], [[BB3]] ]254; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255255; CHECK-NEXT: br label [[EXIT:%.*]]256; CHECK: exit:257; CHECK-NEXT: call void @use(i1 false)258; CHECK-NEXT: call void @use(i1 true)259; CHECK-NEXT: ret i64 [[RES]]260;261entry:262 br i1 %c1, label %bb1, label %bb2263 264bb1:265 br label %bb4266 267bb2:268 br i1 %c2, label %bb3, label %bb4269 270bb3:271 %r = and i64 %a, 255272 br label %bb4273 274bb4:275 %p = phi i64 [ undef, %bb1 ], [ 10, %bb2], [ %r, %bb3 ]276 %res = and i64 %p, 255277 br label %exit278 279exit: ; CVP only simplifies based on ranges for non-local conditions.280 %f.1 = icmp eq i64 %p, 256281 call void @use(i1 %f.1)282 %t.1 = icmp ne i64 %p, 256283 call void @use(i1 %t.1)284 ret i64 %res285}286 287; Same as @constant_range_and_undef_3_incoming_v1, but with different order of288; incoming values.289define i64 @constant_range_and_undef_3_incoming_v3(i1 %c1, i1 %c2, i64 %a) {290; CHECK-LABEL: @constant_range_and_undef_3_incoming_v3(291; CHECK-NEXT: entry:292; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]293; CHECK: bb1:294; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255295; CHECK-NEXT: br label [[BB4:%.*]]296; CHECK: bb2:297; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]298; CHECK: bb3:299; CHECK-NEXT: br label [[BB4]]300; CHECK: bb4:301; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ], [ 10, [[BB3]] ]302; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255303; CHECK-NEXT: br label [[EXIT:%.*]]304; CHECK: exit:305; CHECK-NEXT: call void @use(i1 false)306; CHECK-NEXT: call void @use(i1 true)307; CHECK-NEXT: ret i64 [[RES]]308;309entry:310 br i1 %c1, label %bb1, label %bb2311 312bb1:313 %r = and i64 %a, 255314 br label %bb4315 316bb2:317 br i1 %c2, label %bb3, label %bb4318 319bb3:320 br label %bb4321 322bb4:323 %p = phi i64 [ %r, %bb1 ], [ undef, %bb2], [ 10, %bb3 ]324 %res = and i64 %p, 255325 br label %exit326 327exit: ; CVP only simplifies based on ranges for non-local conditions.328 %f.1 = icmp eq i64 %p, 256329 call void @use(i1 %f.1)330 %t.1 = icmp ne i64 %p, 256331 call void @use(i1 %t.1)332 ret i64 %res333}334 335define i64 @constant_range_and_phi_constant_undef(i1 %c1, i1 %c2, i64 %a) {336; CHECK-LABEL: @constant_range_and_phi_constant_undef(337; CHECK-NEXT: entry:338; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]339; CHECK: bb1:340; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255341; CHECK-NEXT: br label [[BB5:%.*]]342; CHECK: bb2:343; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]344; CHECK: bb3:345; CHECK-NEXT: br label [[BB4]]346; CHECK: bb4:347; CHECK-NEXT: br label [[BB5]]348; CHECK: bb5:349; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB4]] ]350; CHECK-NEXT: br label [[EXIT:%.*]]351; CHECK: exit:352; CHECK-NEXT: call void @use(i1 false)353; CHECK-NEXT: call void @use(i1 true)354; CHECK-NEXT: ret i64 [[P]]355;356entry:357 br i1 %c1, label %bb1, label %bb2358 359bb1:360 %r = and i64 %a, 255361 br label %bb5362 363bb2:364 br i1 %c2, label %bb3, label %bb4365 366bb3:367 br label %bb4368 369bb4:370 %p.1 = phi i64 [ 10, %bb2 ], [ undef, %bb3]371 br label %bb5372 373bb5:374 %p = phi i64 [ %r, %bb1 ], [ %p.1, %bb4]375 %res = and i64 %p, 255376 br label %exit377 378exit: ; CVP only simplifies based on ranges for non-local conditions.379 %f.1 = icmp eq i64 %p, 256380 call void @use(i1 %f.1)381 %t.1 = icmp ne i64 %p, 256382 call void @use(i1 %t.1)383 ret i64 %res384}385 386; Test case for PR68381.387; Because of `undef`, we can only delete the second `and` instruction.388define i32 @constant_range_and_undef_and(i1 %c0, i1 %c1, i8 %v1, i8 %v2) {389; CHECK-LABEL: @constant_range_and_undef_and(390; CHECK-NEXT: start:391; CHECK-NEXT: br i1 [[C0:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]392; CHECK: bb0:393; CHECK-NEXT: [[V1_I32:%.*]] = zext i8 [[V1:%.*]] to i32394; CHECK-NEXT: br label [[BB1]]395; CHECK: bb1:396; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V1_I32]], [[BB0]] ], [ undef, [[START:%.*]] ]397; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]]398; CHECK: bb2:399; CHECK-NEXT: [[V2_I32:%.*]] = zext i8 [[V2:%.*]] to i32400; CHECK-NEXT: [[Y:%.*]] = or i32 [[X]], [[V2_I32]]401; CHECK-NEXT: [[Z:%.*]] = and i32 [[Y]], 255402; CHECK-NEXT: ret i32 [[Z]]403;404start:405 br i1 %c0, label %bb0, label %bb1406 407bb0:408 %v1_i32 = zext i8 %v1 to i32409 br label %bb1410 411bb1:412 %x = phi i32 [ %v1_i32, %bb0 ], [ undef, %start ]413 br i1 %c1, label %bb0, label %bb2414 415bb2:416 %v2_i32 = zext i8 %v2 to i32417 %y = or i32 %x, %v2_i32418 %z = and i32 %y, 255419 %z1 = and i32 %z, 255420 ret i32 %z1421}422