| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 
 | ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
; Test 128-bit shift left in vector registers on z13
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
; Shift left immediate (general case).
define i128 @f1(i128 %a) {
; CHECK-LABEL: f1:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vl %v0, 0(%r3), 3
; CHECK-NEXT:    vrepib %v1, 100
; CHECK-NEXT:    vslb %v0, %v0, %v1
; CHECK-NEXT:    vsl %v0, %v0, %v1
; CHECK-NEXT:    vst %v0, 0(%r2), 3
; CHECK-NEXT:    br %r14
  %res = shl i128 %a, 100
  ret i128 %res
}
; Shift left immediate (< 8 bits).
define i128 @f2(i128 %a) {
; CHECK-LABEL: f2:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vl %v0, 0(%r3), 3
; CHECK-NEXT:    vrepib %v1, 7
; CHECK-NEXT:    vsl %v0, %v0, %v1
; CHECK-NEXT:    vst %v0, 0(%r2), 3
; CHECK-NEXT:    br %r14
  %res = shl i128 %a, 7
  ret i128 %res
}
; Shift left immediate (full bytes).
define i128 @f3(i128 %a) {
; CHECK-LABEL: f3:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vl %v0, 0(%r3), 3
; CHECK-NEXT:    vrepib %v1, 32
; CHECK-NEXT:    vslb %v0, %v0, %v1
; CHECK-NEXT:    vst %v0, 0(%r2), 3
; CHECK-NEXT:    br %r14
  %res = shl i128 %a, 32
  ret i128 %res
}
; Shift left variable.
define i128 @f4(i128 %a, i128 %sh) {
; CHECK-LABEL: f4:
; CHECK:       # %bb.0:
; CHECK-NEXT:    l %r0, 12(%r4)
; CHECK-NEXT:    vlvgp %v1, %r0, %r0
; CHECK-NEXT:    vl %v0, 0(%r3), 3
; CHECK-NEXT:    vrepb %v1, %v1, 15
; CHECK-NEXT:    vslb %v0, %v0, %v1
; CHECK-NEXT:    vsl %v0, %v0, %v1
; CHECK-NEXT:    vst %v0, 0(%r2), 3
; CHECK-NEXT:    br %r14
  %res = shl i128 %a, %sh
  ret i128 %res
}
; Test removal of AND mask with only bottom 7 bits set.
define i128 @f5(i128 %a, i128 %sh) {
; CHECK-LABEL: f5:
; CHECK:       # %bb.0:
; CHECK-NEXT:    l %r0, 12(%r4)
; CHECK-NEXT:    vlvgp %v1, %r0, %r0
; CHECK-NEXT:    vl %v0, 0(%r3), 3
; CHECK-NEXT:    vrepb %v1, %v1, 15
; CHECK-NEXT:    vslb %v0, %v0, %v1
; CHECK-NEXT:    vsl %v0, %v0, %v1
; CHECK-NEXT:    vst %v0, 0(%r2), 3
; CHECK-NEXT:    br %r14
  %and = and i128 %sh, 127
  %shift = shl i128 %a, %and
  ret i128 %shift
}
; Test removal of AND mask including but not limited to bottom 7 bits.
define i128 @f6(i128 %a, i128 %sh) {
; CHECK-LABEL: f6:
; CHECK:       # %bb.0:
; CHECK-NEXT:    l %r0, 12(%r4)
; CHECK-NEXT:    vlvgp %v1, %r0, %r0
; CHECK-NEXT:    vl %v0, 0(%r3), 3
; CHECK-NEXT:    vrepb %v1, %v1, 15
; CHECK-NEXT:    vslb %v0, %v0, %v1
; CHECK-NEXT:    vsl %v0, %v0, %v1
; CHECK-NEXT:    vst %v0, 0(%r2), 3
; CHECK-NEXT:    br %r14
  %and = and i128 %sh, 511
  %shift = shl i128 %a, %and
  ret i128 %shift
}
; Test that AND is not removed when some lower 7 bits are not set.
define i128 @f7(i128 %a, i128 %sh) {
; CHECK-LABEL: f7:
; CHECK:       # %bb.0:
; CHECK-NEXT:    lhi %r0, 63
; CHECK-NEXT:    n %r0, 12(%r4)
; CHECK-NEXT:    vlvgp %v1, %r0, %r0
; CHECK-NEXT:    vl %v0, 0(%r3), 3
; CHECK-NEXT:    vrepb %v1, %v1, 15
; CHECK-NEXT:    vslb %v0, %v0, %v1
; CHECK-NEXT:    vsl %v0, %v0, %v1
; CHECK-NEXT:    vst %v0, 0(%r2), 3
; CHECK-NEXT:    br %r14
  %and = and i128 %sh, 63
  %shift = shl i128 %a, %and
  ret i128 %shift
}
; Test that AND with two register operands is not affected.
define i128 @f8(i128 %a, i128 %b, i128 %sh) {
; CHECK-LABEL: f8:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vl %v1, 0(%r4), 3
; CHECK-NEXT:    vl %v2, 0(%r5), 3
; CHECK-NEXT:    vn %v1, %v2, %v1
; CHECK-NEXT:    vlgvf %r0, %v1, 3
; CHECK-NEXT:    vlvgp %v1, %r0, %r0
; CHECK-NEXT:    vl %v0, 0(%r3), 3
; CHECK-NEXT:    vrepb %v1, %v1, 15
; CHECK-NEXT:    vslb %v0, %v0, %v1
; CHECK-NEXT:    vsl %v0, %v0, %v1
; CHECK-NEXT:    vst %v0, 0(%r2), 3
; CHECK-NEXT:    br %r14
  %and = and i128 %sh, %b
  %shift = shl i128 %a, %and
  ret i128 %shift
}
; Test that AND is not entirely removed if the result is reused.
define i128 @f9(i128 %a, i128 %sh) {
; CHECK-LABEL: f9:
; CHECK:       # %bb.0:
; CHECK-NEXT:    larl %r1, .LCPI8_0
; CHECK-NEXT:    vl %v1, 0(%r4), 3
; CHECK-NEXT:    vl %v2, 0(%r1), 3
; CHECK-NEXT:    vn %v1, %v1, %v2
; CHECK-NEXT:    vlgvf %r0, %v1, 3
; CHECK-NEXT:    vlvgp %v2, %r0, %r0
; CHECK-NEXT:    vl %v0, 0(%r3), 3
; CHECK-NEXT:    vrepb %v2, %v2, 15
; CHECK-NEXT:    vslb %v0, %v0, %v2
; CHECK-NEXT:    vsl %v0, %v0, %v2
; CHECK-NEXT:    vaq %v0, %v1, %v0
; CHECK-NEXT:    vst %v0, 0(%r2), 3
; CHECK-NEXT:    br %r14
  %and = and i128 %sh, 127
  %shift = shl i128 %a, %and
  %reuse = add i128 %and, %shift
  ret i128 %reuse
}
 |