446 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; Test the use of TEST UNDER MASK for 64-bit operations.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s5; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s6 7@g = global i32 08 9; Check the lowest useful TMLL value.10define void @f1(i64 %a) {11; CHECK-LABEL: f1:12; CHECK: # %bb.0: # %entry13; CHECK-NEXT: tmll %r2, 114; CHECK-NEXT: ber %r1415; CHECK-NEXT: .LBB0_1: # %store16; CHECK-NEXT: lgrl %r1, g@GOT17; CHECK-NEXT: mvhi 0(%r1), 118; CHECK-NEXT: br %r1419entry:20 %and = and i64 %a, 121 %cmp = icmp eq i64 %and, 022 br i1 %cmp, label %exit, label %store23 24store:25 store i32 1, ptr@g26 br label %exit27 28exit:29 ret void30}31 32; Check the high end of the TMLL range.33define void @f2(i64 %a) {34; CHECK-LABEL: f2:35; CHECK: # %bb.0: # %entry36; CHECK-NEXT: tmll %r2, 6553537; CHECK-NEXT: bner %r1438; CHECK-NEXT: .LBB1_1: # %store39; CHECK-NEXT: lgrl %r1, g@GOT40; CHECK-NEXT: mvhi 0(%r1), 141; CHECK-NEXT: br %r1442entry:43 %and = and i64 %a, 6553544 %cmp = icmp ne i64 %and, 045 br i1 %cmp, label %exit, label %store46 47store:48 store i32 1, ptr@g49 br label %exit50 51exit:52 ret void53}54 55; Check the lowest useful TMLH value, which is the next value up.56define void @f3(i64 %a) {57; CHECK-LABEL: f3:58; CHECK: # %bb.0: # %entry59; CHECK-NEXT: tmlh %r2, 160; CHECK-NEXT: bner %r1461; CHECK-NEXT: .LBB2_1: # %store62; CHECK-NEXT: lgrl %r1, g@GOT63; CHECK-NEXT: mvhi 0(%r1), 164; CHECK-NEXT: br %r1465entry:66 %and = and i64 %a, 6553667 %cmp = icmp ne i64 %and, 068 br i1 %cmp, label %exit, label %store69 70store:71 store i32 1, ptr@g72 br label %exit73 74exit:75 ret void76}77 78; Check the next value up again, which cannot use TM.79define void @f4(i64 %a) {80; CHECK-LABEL: f4:81; CHECK: # %bb.0: # %entry82; CHECK-NEXT: llilf %r0, 429490175983; CHECK-NEXT: ngr %r0, %r284; CHECK-NEXT: ber %r1485; CHECK-NEXT: .LBB3_1: # %store86; CHECK-NEXT: lgrl %r1, g@GOT87; CHECK-NEXT: mvhi 0(%r1), 188; CHECK-NEXT: br %r1489entry:90 %and = and i64 %a, 429490175991 %cmp = icmp eq i64 %and, 092 br i1 %cmp, label %exit, label %store93 94store:95 store i32 1, ptr@g96 br label %exit97 98exit:99 ret void100}101 102; Check the high end of the TMLH range.103define void @f5(i64 %a) {104; CHECK-LABEL: f5:105; CHECK: # %bb.0: # %entry106; CHECK-NEXT: tmlh %r2, 65535107; CHECK-NEXT: ber %r14108; CHECK-NEXT: .LBB4_1: # %store109; CHECK-NEXT: lgrl %r1, g@GOT110; CHECK-NEXT: mvhi 0(%r1), 1111; CHECK-NEXT: br %r14112entry:113 %and = and i64 %a, 4294901760114 %cmp = icmp eq i64 %and, 0115 br i1 %cmp, label %exit, label %store116 117store:118 store i32 1, ptr@g119 br label %exit120 121exit:122 ret void123}124 125; Check the lowest useful TMHL value.126define void @f6(i64 %a) {127; CHECK-LABEL: f6:128; CHECK: # %bb.0: # %entry129; CHECK-NEXT: tmhl %r2, 1130; CHECK-NEXT: ber %r14131; CHECK-NEXT: .LBB5_1: # %store132; CHECK-NEXT: lgrl %r1, g@GOT133; CHECK-NEXT: mvhi 0(%r1), 1134; CHECK-NEXT: br %r14135entry:136 %and = and i64 %a, 4294967296137 %cmp = icmp eq i64 %and, 0138 br i1 %cmp, label %exit, label %store139 140store:141 store i32 1, ptr@g142 br label %exit143 144exit:145 ret void146}147 148; Check the next value up again, which cannot use TM.149define void @f7(i64 %a) {150; CHECK-LABEL: f7:151; CHECK: # %bb.0: # %entry152; CHECK-NEXT: llihl %r0, 1153; CHECK-NEXT: oill %r0, 1154; CHECK-NEXT: ngr %r0, %r2155; CHECK-NEXT: blr %r14156; CHECK-NEXT: .LBB6_1: # %store157; CHECK-NEXT: lgrl %r1, g@GOT158; CHECK-NEXT: mvhi 0(%r1), 1159; CHECK-NEXT: br %r14160entry:161 %and = and i64 %a, 4294967297162 %cmp = icmp ne i64 %and, 0163 br i1 %cmp, label %exit, label %store164 165store:166 store i32 1, ptr@g167 br label %exit168 169exit:170 ret void171}172 173; Check the high end of the TMHL range.174define void @f8(i64 %a) {175; CHECK-LABEL: f8:176; CHECK: # %bb.0: # %entry177; CHECK-NEXT: tmhl %r2, 65535178; CHECK-NEXT: bner %r14179; CHECK-NEXT: .LBB7_1: # %store180; CHECK-NEXT: lgrl %r1, g@GOT181; CHECK-NEXT: mvhi 0(%r1), 1182; CHECK-NEXT: br %r14183entry:184 %and = and i64 %a, 281470681743360185 %cmp = icmp ne i64 %and, 0186 br i1 %cmp, label %exit, label %store187 188store:189 store i32 1, ptr@g190 br label %exit191 192exit:193 ret void194}195 196; Check the lowest useful TMHH value.197define void @f9(i64 %a) {198; CHECK-LABEL: f9:199; CHECK: # %bb.0: # %entry200; CHECK-NEXT: tmhh %r2, 1201; CHECK-NEXT: bner %r14202; CHECK-NEXT: .LBB8_1: # %store203; CHECK-NEXT: lgrl %r1, g@GOT204; CHECK-NEXT: mvhi 0(%r1), 1205; CHECK-NEXT: br %r14206entry:207 %and = and i64 %a, 281474976710656208 %cmp = icmp ne i64 %and, 0209 br i1 %cmp, label %exit, label %store210 211store:212 store i32 1, ptr@g213 br label %exit214 215exit:216 ret void217}218 219; Check the high end of the TMHH range.220define void @f10(i64 %a) {221; CHECK-LABEL: f10:222; CHECK: # %bb.0: # %entry223; CHECK-NEXT: tmhh %r2, 65535224; CHECK-NEXT: ber %r14225; CHECK-NEXT: .LBB9_1: # %store226; CHECK-NEXT: lgrl %r1, g@GOT227; CHECK-NEXT: mvhi 0(%r1), 1228; CHECK-NEXT: br %r14229entry:230 %and = and i64 %a, 18446462598732840960231 %cmp = icmp eq i64 %and, 0232 br i1 %cmp, label %exit, label %store233 234store:235 store i32 1, ptr@g236 br label %exit237 238exit:239 ret void240}241 242; Check that we can fold an SHL into a TMxx mask.243define void @f11(i64 %a) {244; CHECK-LABEL: f11:245; CHECK: # %bb.0: # %entry246; CHECK-NEXT: tmhl %r2, 32768247; CHECK-NEXT: bner %r14248; CHECK-NEXT: .LBB10_1: # %store249; CHECK-NEXT: lgrl %r1, g@GOT250; CHECK-NEXT: mvhi 0(%r1), 1251; CHECK-NEXT: br %r14252entry:253 %shl = shl i64 %a, 1254 %and = and i64 %shl, 281474976710656255 %cmp = icmp ne i64 %and, 0256 br i1 %cmp, label %exit, label %store257 258store:259 store i32 1, ptr@g260 br label %exit261 262exit:263 ret void264}265 266; Check that we can fold an SHR into a TMxx mask.267define void @f12(i64 %a) {268; CHECK-LABEL: f12:269; CHECK: # %bb.0: # %entry270; CHECK-NEXT: tmhh %r2, 256271; CHECK-NEXT: bner %r14272; CHECK-NEXT: .LBB11_1: # %store273; CHECK-NEXT: lgrl %r1, g@GOT274; CHECK-NEXT: mvhi 0(%r1), 1275; CHECK-NEXT: br %r14276entry:277 %shr = lshr i64 %a, 56278 %and = and i64 %shr, 1279 %cmp = icmp ne i64 %and, 0280 br i1 %cmp, label %exit, label %store281 282store:283 store i32 1, ptr@g284 br label %exit285 286exit:287 ret void288}289 290; Check a case where TMHH can be used to implement a ult comparison.291define void @f13(i64 %a) {292; CHECK-LABEL: f13:293; CHECK: # %bb.0: # %entry294; CHECK-NEXT: tmhh %r2, 49152295; CHECK-NEXT: bnor %r14296; CHECK-NEXT: .LBB12_1: # %store297; CHECK-NEXT: lgrl %r1, g@GOT298; CHECK-NEXT: mvhi 0(%r1), 1299; CHECK-NEXT: br %r14300entry:301 %cmp = icmp ult i64 %a, 13835058055282163712302 br i1 %cmp, label %exit, label %store303 304store:305 store i32 1, ptr@g306 br label %exit307 308exit:309 ret void310}311 312; And again with ule.313define void @f14(i64 %a) {314; CHECK-LABEL: f14:315; CHECK: # %bb.0: # %entry316; CHECK-NEXT: tmhh %r2, 49152317; CHECK-NEXT: bnor %r14318; CHECK-NEXT: .LBB13_1: # %store319; CHECK-NEXT: lgrl %r1, g@GOT320; CHECK-NEXT: mvhi 0(%r1), 1321; CHECK-NEXT: br %r14322entry:323 %cmp = icmp ule i64 %a, 13835058055282163711324 br i1 %cmp, label %exit, label %store325 326store:327 store i32 1, ptr@g328 br label %exit329 330exit:331 ret void332}333 334; And again with ugt.335define void @f15(i64 %a) {336; CHECK-LABEL: f15:337; CHECK: # %bb.0: # %entry338; CHECK-NEXT: tmhh %r2, 49152339; CHECK-NEXT: bor %r14340; CHECK-NEXT: .LBB14_1: # %store341; CHECK-NEXT: lgrl %r1, g@GOT342; CHECK-NEXT: mvhi 0(%r1), 1343; CHECK-NEXT: br %r14344entry:345 %cmp = icmp ugt i64 %a, 13835058055282163711346 br i1 %cmp, label %exit, label %store347 348store:349 store i32 1, ptr@g350 br label %exit351 352exit:353 ret void354}355 356; And again with uge.357define void @f16(i64 %a) {358; CHECK-LABEL: f16:359; CHECK: # %bb.0: # %entry360; CHECK-NEXT: tmhh %r2, 49152361; CHECK-NEXT: bor %r14362; CHECK-NEXT: .LBB15_1: # %store363; CHECK-NEXT: lgrl %r1, g@GOT364; CHECK-NEXT: mvhi 0(%r1), 1365; CHECK-NEXT: br %r14366entry:367 %cmp = icmp uge i64 %a, 13835058055282163712368 br i1 %cmp, label %exit, label %store369 370store:371 store i32 1, ptr@g372 br label %exit373 374exit:375 ret void376}377 378; Decrease the constant from f13 to make TMHH invalid.379define void @f17(i64 %a) {380; CHECK-LABEL: f17:381; CHECK: # %bb.0: # %entry382; CHECK-NEXT: srlg %r0, %r2, 48383; CHECK-NEXT: cgfi %r0, 49151384; CHECK-NEXT: blr %r14385; CHECK-NEXT: .LBB16_1: # %store386; CHECK-NEXT: lgrl %r1, g@GOT387; CHECK-NEXT: mvhi 0(%r1), 1388; CHECK-NEXT: br %r14389entry:390 %cmp = icmp ult i64 %a, 13834776580305453056391 br i1 %cmp, label %exit, label %store392 393store:394 store i32 1, ptr@g395 br label %exit396 397exit:398 ret void399}400 401; Check that we don't use TMHH just to test the top bit.402define void @f18(i64 %a) {403; CHECK-LABEL: f18:404; CHECK: # %bb.0: # %entry405; CHECK-NEXT: cgibhe %r2, 0, 0(%r14)406; CHECK-NEXT: .LBB17_1: # %store407; CHECK-NEXT: lgrl %r1, g@GOT408; CHECK-NEXT: mvhi 0(%r1), 1409; CHECK-NEXT: br %r14410entry:411 %cmp = icmp ult i64 %a, 9223372036854775808412 br i1 %cmp, label %exit, label %store413 414store:415 store i32 1, ptr@g416 br label %exit417 418exit:419 ret void420}421 422; Check that we don't fold a shift if the comparison value423; would need to be shifted out of range424define void @f19(i64 %a) {425; CHECK-LABEL: f19:426; CHECK: # %bb.0: # %entry427; CHECK-NEXT: srlg %r0, %r2, 63428; CHECK-NEXT: cgibl %r0, 3, 0(%r14)429; CHECK-NEXT: .LBB18_1: # %store430; CHECK-NEXT: lgrl %r1, g@GOT431; CHECK-NEXT: mvhi 0(%r1), 1432; CHECK-NEXT: br %r14433entry:434 %shr = lshr i64 %a, 63435 %cmp = icmp ult i64 %shr, 3436 br i1 %cmp, label %exit, label %store437 438store:439 store i32 1, ptr@g440 br label %exit441 442exit:443 ret void444}445 446