1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; Test 32-bit rotates left. 3; 4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 5 6; Check the low end of the RLLG range. 7define i64 @f1(i64 %a) { 8; CHECK-LABEL: f1: 9; CHECK: # %bb.0: 10; CHECK-NEXT: rllg %r2, %r2, 1 11; CHECK-NEXT: br %r14 12 %parta = shl i64 %a, 1 13 %partb = lshr i64 %a, 63 14 %or = or i64 %parta, %partb 15 ret i64 %or 16} 17 18; Check the high end of the defined RLLG range. 19define i64 @f2(i64 %a) { 20; CHECK-LABEL: f2: 21; CHECK: # %bb.0: 22; CHECK-NEXT: rllg %r2, %r2, 63 23; CHECK-NEXT: br %r14 24 %parta = shl i64 %a, 63 25 %partb = lshr i64 %a, 1 26 %or = or i64 %parta, %partb 27 ret i64 %or 28} 29 30; We don't generate shifts by out-of-range values. 31define i64 @f3(i64 %a) { 32; CHECK-LABEL: f3: 33; CHECK: # %bb.0: 34; CHECK-NEXT: lghi %r2, -1 35; CHECK-NEXT: br %r14 36 %parta = shl i64 %a, 64 37 %partb = lshr i64 %a, 0 38 %or = or i64 %parta, %partb 39 ret i64 %or 40} 41 42; Check variable shifts. 43define i64 @f4(i64 %a, i64 %amt) { 44; CHECK-LABEL: f4: 45; CHECK: # %bb.0: 46; CHECK-NEXT: rllg %r2, %r2, 0(%r3) 47; CHECK-NEXT: br %r14 48 %amtb = sub i64 64, %amt 49 %parta = shl i64 %a, %amt 50 %partb = lshr i64 %a, %amtb 51 %or = or i64 %parta, %partb 52 ret i64 %or 53} 54 55; Check shift amounts that have a constant term. 56define i64 @f5(i64 %a, i64 %amt) { 57; CHECK-LABEL: f5: 58; CHECK: # %bb.0: 59; CHECK-NEXT: rllg %r2, %r2, 10(%r3) 60; CHECK-NEXT: br %r14 61 %add = add i64 %amt, 10 62 %sub = sub i64 64, %add 63 %parta = shl i64 %a, %add 64 %partb = lshr i64 %a, %sub 65 %or = or i64 %parta, %partb 66 ret i64 %or 67} 68 69; ...and again with a sign-extended 32-bit shift amount. 70define i64 @f6(i64 %a, i32 %amt) { 71; CHECK-LABEL: f6: 72; CHECK: # %bb.0: 73; CHECK-NEXT: rllg %r2, %r2, 10(%r3) 74; CHECK-NEXT: br %r14 75 %add = add i32 %amt, 10 76 %sub = sub i32 64, %add 77 %addext = sext i32 %add to i64 78 %subext = sext i32 %sub to i64 79 %parta = shl i64 %a, %addext 80 %partb = lshr i64 %a, %subext 81 %or = or i64 %parta, %partb 82 ret i64 %or 83} 84 85; ...and now with a zero-extended 32-bit shift amount. 86define i64 @f7(i64 %a, i32 %amt) { 87; CHECK-LABEL: f7: 88; CHECK: # %bb.0: 89; CHECK-NEXT: rllg %r2, %r2, 10(%r3) 90; CHECK-NEXT: br %r14 91 %add = add i32 %amt, 10 92 %sub = sub i32 64, %add 93 %addext = zext i32 %add to i64 94 %subext = zext i32 %sub to i64 95 %parta = shl i64 %a, %addext 96 %partb = lshr i64 %a, %subext 97 %or = or i64 %parta, %partb 98 ret i64 %or 99} 100 101; Check shift amounts that have the largest in-range constant term, and then 102; mask the amount. 103define i64 @f8(i64 %a, i64 %amt) { 104; CHECK-LABEL: f8: 105; CHECK: # %bb.0: 106; CHECK-NEXT: rllg %r2, %r2, -1(%r3) 107; CHECK-NEXT: br %r14 108 %add = add i64 %amt, 524287 109 %sub = sub i64 64, %add 110 %parta = shl i64 %a, %add 111 %partb = lshr i64 %a, %sub 112 %or = or i64 %parta, %partb 113 ret i64 %or 114} 115 116; Check the next value up, which without masking must use a separate 117; addition. 118define i64 @f9(i64 %a, i64 %amt) { 119; CHECK-LABEL: f9: 120; CHECK: # %bb.0: 121; CHECK-NEXT: afi %r3, 524288 122; CHECK-NEXT: rllg %r2, %r2, 0(%r3) 123; CHECK-NEXT: br %r14 124 %add = add i64 %amt, 524288 125 %sub = sub i64 64, %add 126 %parta = shl i64 %a, %add 127 %partb = lshr i64 %a, %sub 128 %or = or i64 %parta, %partb 129 ret i64 %or 130} 131 132; Check cases where 1 is subtracted from the shift amount. 133define i64 @f10(i64 %a, i64 %amt) { 134; CHECK-LABEL: f10: 135; CHECK: # %bb.0: 136; CHECK-NEXT: rllg %r2, %r2, -1(%r3) 137; CHECK-NEXT: br %r14 138 %suba = sub i64 %amt, 1 139 %subb = sub i64 64, %suba 140 %parta = shl i64 %a, %suba 141 %partb = lshr i64 %a, %subb 142 %or = or i64 %parta, %partb 143 ret i64 %or 144} 145 146; Check the lowest value that can be subtracted from the shift amount. 147; Again, we could mask the shift amount instead. 148define i64 @f11(i64 %a, i64 %amt) { 149; CHECK-LABEL: f11: 150; CHECK: # %bb.0: 151; CHECK-NEXT: rllg %r2, %r2, -524288(%r3) 152; CHECK-NEXT: br %r14 153 %suba = sub i64 %amt, 524288 154 %subb = sub i64 64, %suba 155 %parta = shl i64 %a, %suba 156 %partb = lshr i64 %a, %subb 157 %or = or i64 %parta, %partb 158 ret i64 %or 159} 160 161; Check the next value down, masking the amount removes the addition. 162define i64 @f12(i64 %a, i64 %amt) { 163; CHECK-LABEL: f12: 164; CHECK: # %bb.0: 165; CHECK-NEXT: rllg %r2, %r2, -1(%r3) 166; CHECK-NEXT: br %r14 167 %suba = sub i64 %amt, 524289 168 %subb = sub i64 64, %suba 169 %parta = shl i64 %a, %suba 170 %partb = lshr i64 %a, %subb 171 %or = or i64 %parta, %partb 172 ret i64 %or 173} 174 175; Check that we don't try to generate "indexed" shifts. 176define i64 @f13(i64 %a, i64 %b, i64 %c) { 177; CHECK-LABEL: f13: 178; CHECK: # %bb.0: 179; CHECK-NEXT: agr %r3, %r4 180; CHECK-NEXT: rllg %r2, %r2, 0(%r3) 181; CHECK-NEXT: br %r14 182 %add = add i64 %b, %c 183 %sub = sub i64 64, %add 184 %parta = shl i64 %a, %add 185 %partb = lshr i64 %a, %sub 186 %or = or i64 %parta, %partb 187 ret i64 %or 188} 189 190; Check that the shift amount uses an address register. It cannot be in %r0. 191define i64 @f14(i64 %a, ptr %ptr) { 192; CHECK-LABEL: f14: 193; CHECK: # %bb.0: 194; CHECK-NEXT: l %r1, 4(%r3) 195; CHECK-NEXT: rllg %r2, %r2, 0(%r1) 196; CHECK-NEXT: br %r14 197 %amt = load i64, ptr %ptr 198 %amtb = sub i64 64, %amt 199 %parta = shl i64 %a, %amt 200 %partb = lshr i64 %a, %amtb 201 %or = or i64 %parta, %partb 202 ret i64 %or 203} 204