317 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; Test 32-bit rotates left.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s5 6; Check the low end of the RLL range.7define i32 @f1(i32 %a) {8; CHECK-LABEL: f1:9; CHECK: # %bb.0:10; CHECK-NEXT: rll %r2, %r2, 111; CHECK-NEXT: br %r1412 %parta = shl i32 %a, 113 %partb = lshr i32 %a, 3114 %or = or i32 %parta, %partb15 ret i32 %or16}17 18; Check the high end of the defined RLL range.19define i32 @f2(i32 %a) {20; CHECK-LABEL: f2:21; CHECK: # %bb.0:22; CHECK-NEXT: rll %r2, %r2, 3123; CHECK-NEXT: br %r1424 %parta = shl i32 %a, 3125 %partb = lshr i32 %a, 126 %or = or i32 %parta, %partb27 ret i32 %or28}29 30; We don't generate shifts by out-of-range values.31define i32 @f3(i32 %a) {32; CHECK-LABEL: f3:33; CHECK: # %bb.0:34; CHECK-NEXT: lhi %r2, -135; CHECK-NEXT: br %r1436 %parta = shl i32 %a, 3237 %partb = lshr i32 %a, 038 %or = or i32 %parta, %partb39 ret i32 %or40}41 42; Check variable shifts.43define i32 @f4(i32 %a, i32 %amt) {44; CHECK-LABEL: f4:45; CHECK: # %bb.0:46; CHECK-NEXT: rll %r2, %r2, 0(%r3)47; CHECK-NEXT: br %r1448 %amtb = sub i32 32, %amt49 %parta = shl i32 %a, %amt50 %partb = lshr i32 %a, %amtb51 %or = or i32 %parta, %partb52 ret i32 %or53}54 55; Check shift amounts that have a constant term.56define i32 @f5(i32 %a, i32 %amt) {57; CHECK-LABEL: f5:58; CHECK: # %bb.0:59; CHECK-NEXT: rll %r2, %r2, 10(%r3)60; CHECK-NEXT: br %r1461 %add = add i32 %amt, 1062 %sub = sub i32 32, %add63 %parta = shl i32 %a, %add64 %partb = lshr i32 %a, %sub65 %or = or i32 %parta, %partb66 ret i32 %or67}68 69; ...and again with a truncated 64-bit shift amount.70define i32 @f6(i32 %a, i64 %amt) {71; CHECK-LABEL: f6:72; CHECK: # %bb.0:73; CHECK-NEXT: rll %r2, %r2, 10(%r3)74; CHECK-NEXT: br %r1475 %add = add i64 %amt, 1076 %addtrunc = trunc i64 %add to i3277 %sub = sub i32 32, %addtrunc78 %parta = shl i32 %a, %addtrunc79 %partb = lshr i32 %a, %sub80 %or = or i32 %parta, %partb81 ret i32 %or82}83 84; ...and again with a different truncation representation.85define i32 @f7(i32 %a, i64 %amt) {86; CHECK-LABEL: f7:87; CHECK: # %bb.0:88; CHECK-NEXT: rll %r2, %r2, 10(%r3)89; CHECK-NEXT: br %r1490 %add = add i64 %amt, 1091 %sub = sub i64 32, %add92 %addtrunc = trunc i64 %add to i3293 %subtrunc = trunc i64 %sub to i3294 %parta = shl i32 %a, %addtrunc95 %partb = lshr i32 %a, %subtrunc96 %or = or i32 %parta, %partb97 ret i32 %or98}99 100; Check shift amounts that have the largest in-range constant term, and then101; mask the amount.102define i32 @f8(i32 %a, i32 %amt) {103; CHECK-LABEL: f8:104; CHECK: # %bb.0:105; CHECK-NEXT: rll %r2, %r2, -1(%r3)106; CHECK-NEXT: br %r14107 %add = add i32 %amt, 524287108 %sub = sub i32 32, %add109 %parta = shl i32 %a, %add110 %partb = lshr i32 %a, %sub111 %or = or i32 %parta, %partb112 ret i32 %or113}114 115; Check the next value up, which without masking must use a separate116; addition.117define i32 @f9(i32 %a, i32 %amt) {118; CHECK-LABEL: f9:119; CHECK: # %bb.0:120; CHECK-NEXT: afi %r3, 524288121; CHECK-NEXT: rll %r2, %r2, 0(%r3)122; CHECK-NEXT: br %r14123 %add = add i32 %amt, 524288124 %sub = sub i32 32, %add125 %parta = shl i32 %a, %add126 %partb = lshr i32 %a, %sub127 %or = or i32 %parta, %partb128 ret i32 %or129}130 131; Check cases where 1 is subtracted from the shift amount.132define i32 @f10(i32 %a, i32 %amt) {133; CHECK-LABEL: f10:134; CHECK: # %bb.0:135; CHECK-NEXT: rll %r2, %r2, -1(%r3)136; CHECK-NEXT: br %r14137 %suba = sub i32 %amt, 1138 %subb = sub i32 32, %suba139 %parta = shl i32 %a, %suba140 %partb = lshr i32 %a, %subb141 %or = or i32 %parta, %partb142 ret i32 %or143}144 145; Check the lowest value that can be subtracted from the shift amount.146; Again, we could mask the shift amount instead.147define i32 @f11(i32 %a, i32 %amt) {148; CHECK-LABEL: f11:149; CHECK: # %bb.0:150; CHECK-NEXT: rll %r2, %r2, -524288(%r3)151; CHECK-NEXT: br %r14152 %suba = sub i32 %amt, 524288153 %subb = sub i32 32, %suba154 %parta = shl i32 %a, %suba155 %partb = lshr i32 %a, %subb156 %or = or i32 %parta, %partb157 ret i32 %or158}159 160; Check the next value down, masking the amount removes the addition.161define i32 @f12(i32 %a, i32 %amt) {162; CHECK-LABEL: f12:163; CHECK: # %bb.0:164; CHECK-NEXT: rll %r2, %r2, -1(%r3)165; CHECK-NEXT: br %r14166 %suba = sub i32 %amt, 524289167 %subb = sub i32 32, %suba168 %parta = shl i32 %a, %suba169 %partb = lshr i32 %a, %subb170 %or = or i32 %parta, %partb171 ret i32 %or172}173 174; Check that we don't try to generate "indexed" shifts.175define i32 @f13(i32 %a, i32 %b, i32 %c) {176; CHECK-LABEL: f13:177; CHECK: # %bb.0:178; CHECK-NEXT: ar %r3, %r4179; CHECK-NEXT: rll %r2, %r2, 0(%r3)180; CHECK-NEXT: br %r14181 %add = add i32 %b, %c182 %sub = sub i32 32, %add183 %parta = shl i32 %a, %add184 %partb = lshr i32 %a, %sub185 %or = or i32 %parta, %partb186 ret i32 %or187}188 189; Check that the shift amount uses an address register. It cannot be in %r0.190define i32 @f14(i32 %a, ptr %ptr) {191; CHECK-LABEL: f14:192; CHECK: # %bb.0:193; CHECK-NEXT: l %r1, 0(%r3)194; CHECK-NEXT: rll %r2, %r2, 0(%r1)195; CHECK-NEXT: br %r14196 %amt = load i32, ptr %ptr197 %amtb = sub i32 32, %amt198 %parta = shl i32 %a, %amt199 %partb = lshr i32 %a, %amtb200 %or = or i32 %parta, %partb201 ret i32 %or202}203 204; Check another form of f5, which is the one produced by running f5 through205; instcombine.206define i32 @f15(i32 %a, i32 %amt) {207; CHECK-LABEL: f15:208; CHECK: # %bb.0:209; CHECK-NEXT: rll %r2, %r2, 10(%r3)210; CHECK-NEXT: br %r14211 %add = add i32 %amt, 10212 %sub = sub i32 22, %amt213 %parta = shl i32 %a, %add214 %partb = lshr i32 %a, %sub215 %or = or i32 %parta, %partb216 ret i32 %or217}218 219; Likewise for f7.220define i32 @f16(i32 %a, i64 %amt) {221; CHECK-LABEL: f16:222; CHECK: # %bb.0:223; CHECK-NEXT: rll %r2, %r2, 10(%r3)224; CHECK-NEXT: br %r14225 %add = add i64 %amt, 10226 %sub = sub i64 22, %amt227 %addtrunc = trunc i64 %add to i32228 %subtrunc = trunc i64 %sub to i32229 %parta = shl i32 %a, %addtrunc230 %partb = lshr i32 %a, %subtrunc231 %or = or i32 %parta, %partb232 ret i32 %or233}234 235; Check cases where (-x & 31) is used instead of 32 - x.236define i32 @f17(i32 %x, i32 %y) {237; CHECK-LABEL: f17:238; CHECK: # %bb.0: # %entry239; CHECK-NEXT: rll %r2, %r2, 0(%r3)240; CHECK-NEXT: br %r14241entry:242 %shl = shl i32 %x, %y243 %sub = sub i32 0, %y244 %and = and i32 %sub, 31245 %shr = lshr i32 %x, %and246 %or = or i32 %shr, %shl247 ret i32 %or248}249 250; ...and again with ((32 - x) & 31).251define i32 @f18(i32 %x, i32 %y) {252; CHECK-LABEL: f18:253; CHECK: # %bb.0: # %entry254; CHECK-NEXT: rll %r2, %r2, 0(%r3)255; CHECK-NEXT: br %r14256entry:257 %shl = shl i32 %x, %y258 %sub = sub i32 32, %y259 %and = and i32 %sub, 31260 %shr = lshr i32 %x, %and261 %or = or i32 %shr, %shl262 ret i32 %or263}264 265; This is not a rotation.266define i32 @f19(i32 %x, i32 %y) {267; CHECK-LABEL: f19:268; CHECK: # %bb.0: # %entry269; CHECK-NEXT: lr %r0, %r2270; CHECK-NEXT: sll %r0, 0(%r3)271; CHECK-NEXT: lhi %r1, 16272; CHECK-NEXT: sr %r1, %r3273; CHECK-NEXT: nill %r1, 31274; CHECK-NEXT: srl %r2, 0(%r1)275; CHECK-NEXT: or %r2, %r0276; CHECK-NEXT: br %r14277entry:278 %shl = shl i32 %x, %y279 %sub = sub i32 16, %y280 %and = and i32 %sub, 31281 %shr = lshr i32 %x, %and282 %or = or i32 %shr, %shl283 ret i32 %or284}285 286; Repeat f17 with an addition on the shift count.287define i32 @f20(i32 %x, i32 %y) {288; CHECK-LABEL: f20:289; CHECK: # %bb.0: # %entry290; CHECK-NEXT: rll %r2, %r2, 199(%r3)291; CHECK-NEXT: br %r14292entry:293 %add = add i32 %y, 199294 %shl = shl i32 %x, %add295 %sub = sub i32 0, %add296 %and = and i32 %sub, 31297 %shr = lshr i32 %x, %and298 %or = or i32 %shr, %shl299 ret i32 %or300}301 302; ...and again with the InstCombine version.303define i32 @f21(i32 %x, i32 %y) {304; CHECK-LABEL: f21:305; CHECK: # %bb.0: # %entry306; CHECK-NEXT: rll %r2, %r2, 199(%r3)307; CHECK-NEXT: br %r14308entry:309 %add = add i32 %y, 199310 %shl = shl i32 %x, %add311 %sub = sub i32 -199, %y312 %and = and i32 %sub, 31313 %shr = lshr i32 %x, %and314 %or = or i32 %shr, %shl315 ret i32 %or316}317