1 2 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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
@var8 = global i8 0
@var16 = global i16 0
@var32 = global i32 0
@var64 = global i64 0
define void @addsub_i8rhs() {
; CHECK-LABEL: addsub_i8rhs:
%val8_tmp = load i8* @var8
%lhs32 = load i32* @var32
%lhs64 = load i64* @var64
; Need this to prevent extension upon load and give a vanilla i8 operand.
%val8 = add i8 %val8_tmp, 123
; Zero-extending to 32-bits
%rhs32_zext = zext i8 %val8 to i32
%res32_zext = add i32 %lhs32, %rhs32_zext
store volatile i32 %res32_zext, i32* @var32
; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, uxtb
%rhs32_zext_shift = shl i32 %rhs32_zext, 3
%res32_zext_shift = add i32 %lhs32, %rhs32_zext_shift
store volatile i32 %res32_zext_shift, i32* @var32
; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, uxtb #3
; Zero-extending to 64-bits
%rhs64_zext = zext i8 %val8 to i64
%res64_zext = add i64 %lhs64, %rhs64_zext
store volatile i64 %res64_zext, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxtb
%rhs64_zext_shift = shl i64 %rhs64_zext, 1
%res64_zext_shift = add i64 %lhs64, %rhs64_zext_shift
store volatile i64 %res64_zext_shift, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxtb #1
; Sign-extending to 32-bits
%rhs32_sext = sext i8 %val8 to i32
%res32_sext = add i32 %lhs32, %rhs32_sext
store volatile i32 %res32_sext, i32* @var32
; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, sxtb
%rhs32_sext_shift = shl i32 %rhs32_sext, 1
%res32_sext_shift = add i32 %lhs32, %rhs32_sext_shift
store volatile i32 %res32_sext_shift, i32* @var32
; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, sxtb #1
; Sign-extending to 64-bits
%rhs64_sext = sext i8 %val8 to i64
%res64_sext = add i64 %lhs64, %rhs64_sext
store volatile i64 %res64_sext, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxtb
%rhs64_sext_shift = shl i64 %rhs64_sext, 4
%res64_sext_shift = add i64 %lhs64, %rhs64_sext_shift
store volatile i64 %res64_sext_shift, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxtb #4
; CMP variants
%tst = icmp slt i32 %lhs32, %rhs32_zext
br i1 %tst, label %end, label %test2
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}, uxtb
test2:
%cmp_sext = sext i8 %val8 to i64
%tst2 = icmp eq i64 %lhs64, %cmp_sext
br i1 %tst2, label %other, label %end
; CHECK: cmp {{x[0-9]+}}, {{w[0-9]+}}, sxtb
other:
store volatile i32 %lhs32, i32* @var32
ret void
end:
ret void
}
define void @addsub_i16rhs() {
; CHECK-LABEL: addsub_i16rhs:
%val16_tmp = load i16* @var16
%lhs32 = load i32* @var32
%lhs64 = load i64* @var64
; Need this to prevent extension upon load and give a vanilla i16 operand.
%val16 = add i16 %val16_tmp, 123
; Zero-extending to 32-bits
%rhs32_zext = zext i16 %val16 to i32
%res32_zext = add i32 %lhs32, %rhs32_zext
store volatile i32 %res32_zext, i32* @var32
; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, uxth
%rhs32_zext_shift = shl i32 %rhs32_zext, 3
%res32_zext_shift = add i32 %lhs32, %rhs32_zext_shift
store volatile i32 %res32_zext_shift, i32* @var32
; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, uxth #3
; Zero-extending to 64-bits
%rhs64_zext = zext i16 %val16 to i64
%res64_zext = add i64 %lhs64, %rhs64_zext
store volatile i64 %res64_zext, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxth
%rhs64_zext_shift = shl i64 %rhs64_zext, 1
%res64_zext_shift = add i64 %lhs64, %rhs64_zext_shift
store volatile i64 %res64_zext_shift, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxth #1
; Sign-extending to 32-bits
%rhs32_sext = sext i16 %val16 to i32
%res32_sext = add i32 %lhs32, %rhs32_sext
store volatile i32 %res32_sext, i32* @var32
; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, sxth
%rhs32_sext_shift = shl i32 %rhs32_sext, 1
%res32_sext_shift = add i32 %lhs32, %rhs32_sext_shift
store volatile i32 %res32_sext_shift, i32* @var32
; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, sxth #1
; Sign-extending to 64-bits
%rhs64_sext = sext i16 %val16 to i64
%res64_sext = add i64 %lhs64, %rhs64_sext
store volatile i64 %res64_sext, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxth
%rhs64_sext_shift = shl i64 %rhs64_sext, 4
%res64_sext_shift = add i64 %lhs64, %rhs64_sext_shift
store volatile i64 %res64_sext_shift, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxth #4
; CMP variants
%tst = icmp slt i32 %lhs32, %rhs32_zext
br i1 %tst, label %end, label %test2
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}, uxth
test2:
%cmp_sext = sext i16 %val16 to i64
%tst2 = icmp eq i64 %lhs64, %cmp_sext
br i1 %tst2, label %other, label %end
; CHECK: cmp {{x[0-9]+}}, {{w[0-9]+}}, sxth
other:
store volatile i32 %lhs32, i32* @var32
ret void
end:
ret void
}
; N.b. we could probably check more here ("add w2, w3, w1, uxtw" for
; example), but the remaining instructions are probably not idiomatic
; in the face of "add/sub (shifted register)" so I don't intend to.
define void @addsub_i32rhs() {
; CHECK-LABEL: addsub_i32rhs:
%val32_tmp = load i32* @var32
%lhs64 = load i64* @var64
%val32 = add i32 %val32_tmp, 123
%rhs64_zext = zext i32 %val32 to i64
%res64_zext = add i64 %lhs64, %rhs64_zext
store volatile i64 %res64_zext, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxtw
%rhs64_zext_shift = shl i64 %rhs64_zext, 2
%res64_zext_shift = add i64 %lhs64, %rhs64_zext_shift
store volatile i64 %res64_zext_shift, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxtw #2
%rhs64_sext = sext i32 %val32 to i64
%res64_sext = add i64 %lhs64, %rhs64_sext
store volatile i64 %res64_sext, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxtw
%rhs64_sext_shift = shl i64 %rhs64_sext, 2
%res64_sext_shift = add i64 %lhs64, %rhs64_sext_shift
store volatile i64 %res64_sext_shift, i64* @var64
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxtw #2
ret void
}
|