427 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=sccp %s | FileCheck %s3 4declare void @use(i1)5 6define void @and_range_limit(i64 %a) {7; CHECK-LABEL: @and_range_limit(8; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 2559; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[R]], 1510; CHECK-NEXT: call void @use(i1 [[C_0]])11; CHECK-NEXT: call void @use(i1 true)12; CHECK-NEXT: [[C_2:%.*]] = icmp eq i64 [[R]], 10013; CHECK-NEXT: call void @use(i1 [[C_2]])14; CHECK-NEXT: call void @use(i1 false)15; CHECK-NEXT: [[C_4:%.*]] = icmp ne i64 [[R]], 10016; CHECK-NEXT: call void @use(i1 [[C_4]])17; CHECK-NEXT: call void @use(i1 true)18; CHECK-NEXT: ret void19;20 %r = and i64 %a, 25521 %c.0 = icmp slt i64 %r, 1522 call void @use(i1 %c.0)23 %c.1 = icmp slt i64 %r, 25624 call void @use(i1 %c.1)25 %c.2 = icmp eq i64 %r, 10026 call void @use(i1 %c.2)27 %c.3 = icmp eq i64 %r, 30028 call void @use(i1 %c.3)29 %c.4 = icmp ne i64 %r, 10030 call void @use(i1 %c.4)31 %c.5 = icmp ne i64 %r, 30032 call void @use(i1 %c.5)33 ret void34}35 36; Below are test cases for PR44949.37 38; We can remove `%res = and i64 %p, 255`, because %r = 0 and we can eliminate39; %p as well.40define i64 @constant_and_undef(i1 %c1, i64 %a) {41; CHECK-LABEL: @constant_and_undef(42; CHECK-NEXT: entry:43; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]44; CHECK: bb1:45; CHECK-NEXT: br label [[BB3:%.*]]46; CHECK: bb2:47; CHECK-NEXT: br label [[BB3]]48; CHECK: bb3:49; CHECK-NEXT: ret i64 050;51entry:52 br i1 %c1, label %bb1, label %bb253 54bb1:55 br label %bb356 57bb2:58 %r = and i64 %a, 059 br label %bb360 61bb3:62 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]63 %res = and i64 %p, 25564 ret i64 %res65}66 67; Check that we go to overdefined when merging a constant range with undef. We68; cannot remove '%res = and i64 %p, 255'.69define i64 @constant_range_and_undef(i1 %cond, i64 %a) {70; CHECK-LABEL: @constant_range_and_undef(71; CHECK-NEXT: entry:72; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]73; CHECK: bb1:74; CHECK-NEXT: br label [[BB3:%.*]]75; CHECK: bb2:76; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 25577; CHECK-NEXT: br label [[BB3]]78; CHECK: bb3:79; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]80; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 25581; CHECK-NEXT: ret i64 [[RES]]82;83entry:84 br i1 %cond, label %bb1, label %bb285 86bb1:87 br label %bb388 89bb2:90 %r = and i64 %a, 25591 br label %bb392 93bb3:94 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]95 %res = and i64 %p, 25596 ret i64 %res97}98 99; Same as @constant_range_and_undef, with the undef coming from the other100; block.101define i64 @constant_range_and_undef_switched_incoming(i1 %cond, i64 %a) {102; CHECK-LABEL: @constant_range_and_undef_switched_incoming(103; CHECK-NEXT: entry:104; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]105; CHECK: bb1:106; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255107; CHECK-NEXT: br label [[BB3:%.*]]108; CHECK: bb2:109; CHECK-NEXT: br label [[BB3]]110; CHECK: bb3:111; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ]112; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255113; CHECK-NEXT: ret i64 [[RES]]114;115entry:116 br i1 %cond, label %bb1, label %bb2117 118bb1:119 %r = and i64 %a, 255120 br label %bb3121 122bb2:123 br label %bb3124 125bb3:126 %p = phi i64 [ %r, %bb1 ], [ undef, %bb2 ]127 %res = and i64 %p, 255128 ret i64 %res129}130 131define i64 @constant_range_and_255_100(i1 %cond, i64 %a) {132; CHECK-LABEL: @constant_range_and_255_100(133; CHECK-NEXT: entry:134; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]135; CHECK: bb1:136; CHECK-NEXT: [[R_1:%.*]] = and i64 [[A:%.*]], 100137; CHECK-NEXT: br label [[BB3:%.*]]138; CHECK: bb2:139; CHECK-NEXT: [[R_2:%.*]] = and i64 [[A]], 255140; CHECK-NEXT: br label [[BB3]]141; CHECK: bb3:142; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R_1]], [[BB1]] ], [ [[R_2]], [[BB2]] ]143; CHECK-NEXT: call void @use(i1 true)144; CHECK-NEXT: ret i64 [[P]]145;146entry:147 br i1 %cond, label %bb1, label %bb2148 149bb1:150 %r.1 = and i64 %a, 100151 br label %bb3152 153bb2:154 %r.2 = and i64 %a, 255155 br label %bb3156 157bb3:158 %p = phi i64 [ %r.1, %bb1 ], [ %r.2, %bb2 ]159 %p.and = and i64 %p, 255160 %c = icmp ult i64 %p.and, 256161 call void @use(i1 %c)162 ret i64 %p.and163}164 165 166define i64 @constant_range_and_undef2(i1 %c1, i1 %c2, i64 %a) {167; CHECK-LABEL: @constant_range_and_undef2(168; CHECK-NEXT: entry:169; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]170; CHECK: bb1:171; CHECK-NEXT: [[V1:%.*]] = add i64 undef, undef172; CHECK-NEXT: br label [[BB3:%.*]]173; CHECK: bb2:174; CHECK-NEXT: [[V2:%.*]] = and i64 [[A:%.*]], 255175; CHECK-NEXT: br label [[BB3]]176; CHECK: bb3:177; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[V1]], [[BB1]] ], [ [[V2]], [[BB2]] ]178; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB4:%.*]], label [[BB5:%.*]]179; CHECK: bb4:180; CHECK-NEXT: br label [[BB6:%.*]]181; CHECK: bb5:182; CHECK-NEXT: [[V3:%.*]] = and i64 [[A]], 255183; CHECK-NEXT: br label [[BB6]]184; CHECK: bb6:185; CHECK-NEXT: [[P2:%.*]] = phi i64 [ [[P]], [[BB4]] ], [ [[V3]], [[BB5]] ]186; CHECK-NEXT: [[RES:%.*]] = and i64 [[P2]], 255187; CHECK-NEXT: ret i64 [[RES]]188;189entry:190 br i1 %c1, label %bb1, label %bb2191 192bb1:193 %v1 = add i64 undef, undef194 br label %bb3195 196bb2:197 %v2 = and i64 %a, 255198 br label %bb3199 200bb3:201 %p = phi i64 [ %v1, %bb1 ], [ %v2, %bb2 ]202 br i1 %c2, label %bb4, label %bb5203 204bb4:205 br label %bb6206 207bb5:208 %v3 = and i64 %a, 255209 br label %bb6210 211bb6:212 %p2 = phi i64 [ %p, %bb4 ], [ %v3, %bb5 ]213 %res = and i64 %p2, 255214 ret i64 %res215}216 217define i1 @constant_range_and_undef_3(i1 %cond, i64 %a) {218; CHECK-LABEL: @constant_range_and_undef_3(219; CHECK-NEXT: entry:220; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]221; CHECK: bb1:222; CHECK-NEXT: br label [[BB3:%.*]]223; CHECK: bb2:224; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255225; CHECK-NEXT: br label [[BB3]]226; CHECK: bb3:227; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]228; CHECK-NEXT: ret i1 true229;230entry:231 br i1 %cond, label %bb1, label %bb2232 233bb1:234 br label %bb3235 236bb2:237 %r = and i64 %a, 255238 br label %bb3239 240bb3:241 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]242 %c = icmp ult i64 %p, 256243 ret i1 %c244}245 246define i1 @constant_range_and_undef_3_switched_incoming(i1 %cond, i64 %a) {247; CHECK-LABEL: @constant_range_and_undef_3_switched_incoming(248; CHECK-NEXT: entry:249; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]250; CHECK: bb1:251; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255252; CHECK-NEXT: br label [[BB3:%.*]]253; CHECK: bb2:254; CHECK-NEXT: br label [[BB3]]255; CHECK: bb3:256; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ]257; CHECK-NEXT: ret i1 true258;259entry:260 br i1 %cond, label %bb1, label %bb2261 262bb1:263 %r = and i64 %a, 255264 br label %bb3265 266bb2:267 br label %bb3268 269bb3:270 %p = phi i64 [ %r, %bb1 ], [ undef, %bb2 ]271 %c = icmp ult i64 %p, 256272 ret i1 %c273}274 275; Same as @constant_range_and_undef, but with 3 incoming276; values: undef, a constant and a constant range.277define i64 @constant_range_and_undef_3_incoming_v1(i1 %c1, i1 %c2, i64 %a) {278; CHECK-LABEL: @constant_range_and_undef_3_incoming_v1(279; CHECK-NEXT: entry:280; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]281; CHECK: bb1:282; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255283; CHECK-NEXT: br label [[BB4:%.*]]284; CHECK: bb2:285; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]286; CHECK: bb3:287; CHECK-NEXT: br label [[BB4]]288; CHECK: bb4:289; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB2]] ], [ undef, [[BB3]] ]290; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255291; CHECK-NEXT: ret i64 [[RES]]292;293entry:294 br i1 %c1, label %bb1, label %bb2295 296bb1:297 %r = and i64 %a, 255298 br label %bb4299 300bb2:301 br i1 %c2, label %bb3, label %bb4302 303bb3:304 br label %bb4305 306bb4:307 %p = phi i64 [ %r, %bb1 ], [ 10, %bb2], [ undef, %bb3 ]308 %res = and i64 %p, 255309 ret i64 %res310}311 312; Same as @constant_range_and_undef_3_incoming_v1, but with different order of313; incoming values.314define i64 @constant_range_and_undef_3_incoming_v2(i1 %c1, i1 %c2, i64 %a) {315; CHECK-LABEL: @constant_range_and_undef_3_incoming_v2(316; CHECK-NEXT: entry:317; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]318; CHECK: bb1:319; CHECK-NEXT: br label [[BB4:%.*]]320; CHECK: bb2:321; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]322; CHECK: bb3:323; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255324; CHECK-NEXT: br label [[BB4]]325; CHECK: bb4:326; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ 10, [[BB2]] ], [ [[R]], [[BB3]] ]327; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255328; CHECK-NEXT: ret i64 [[RES]]329;330entry:331 br i1 %c1, label %bb1, label %bb2332 333bb1:334 br label %bb4335 336bb2:337 br i1 %c2, label %bb3, label %bb4338 339bb3:340 %r = and i64 %a, 255341 br label %bb4342 343bb4:344 %p = phi i64 [ undef, %bb1 ], [ 10, %bb2], [ %r, %bb3 ]345 %res = and i64 %p, 255346 ret i64 %res347}348 349; Same as @constant_range_and_undef_3_incoming_v1, but with different order of350; incoming values.351define i64 @constant_range_and_undef_3_incoming_v3(i1 %c1, i1 %c2, i64 %a) {352; CHECK-LABEL: @constant_range_and_undef_3_incoming_v3(353; CHECK-NEXT: entry:354; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]355; CHECK: bb1:356; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255357; CHECK-NEXT: br label [[BB4:%.*]]358; CHECK: bb2:359; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]360; CHECK: bb3:361; CHECK-NEXT: br label [[BB4]]362; CHECK: bb4:363; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ], [ 10, [[BB3]] ]364; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255365; CHECK-NEXT: ret i64 [[RES]]366;367entry:368 br i1 %c1, label %bb1, label %bb2369 370bb1:371 %r = and i64 %a, 255372 br label %bb4373 374bb2:375 br i1 %c2, label %bb3, label %bb4376 377bb3:378 br label %bb4379 380bb4:381 %p = phi i64 [ %r, %bb1 ], [ undef, %bb2], [ 10, %bb3 ]382 %res = and i64 %p, 255383 ret i64 %res384}385 386 387define i64 @constant_range_and_phi_constant_undef(i1 %c1, i1 %c2, i64 %a) {388; CHECK-LABEL: @constant_range_and_phi_constant_undef(389; CHECK-NEXT: entry:390; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]391; CHECK: bb1:392; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255393; CHECK-NEXT: br label [[BB5:%.*]]394; CHECK: bb2:395; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]396; CHECK: bb3:397; CHECK-NEXT: br label [[BB4]]398; CHECK: bb4:399; CHECK-NEXT: br label [[BB5]]400; CHECK: bb5:401; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB4]] ]402; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255403; CHECK-NEXT: ret i64 [[RES]]404;405entry:406 br i1 %c1, label %bb1, label %bb2407 408bb1:409 %r = and i64 %a, 255410 br label %bb5411 412bb2:413 br i1 %c2, label %bb3, label %bb4414 415bb3:416 br label %bb4417 418bb4:419 %p.1 = phi i64 [ 10, %bb2 ], [ undef, %bb3]420 br label %bb5421 422bb5:423 %p = phi i64 [ %r, %bb1 ], [ %p.1, %bb4]424 %res = and i64 %p, 255425 ret i64 %res426}427