switch (RetVT.SimpleTy) {
default: return 0;
case MVT::i8:
+ Opc = AArch64::UBFMWri; ImmR = -Shift % 32; ImmS = 7 - Shift; break;
case MVT::i16:
+ Opc = AArch64::UBFMWri; ImmR = -Shift % 32; ImmS = 15 - Shift; break;
case MVT::i32:
- RetVT = MVT::i32;
Opc = AArch64::UBFMWri; ImmR = -Shift % 32; ImmS = 31 - Shift; break;
case MVT::i64:
Opc = AArch64::UBFMXri; ImmR = -Shift % 64; ImmS = 63 - Shift; break;
}
+ RetVT.SimpleTy = std::max(MVT::i32, RetVT.SimpleTy);
return FastEmitInst_rii(Opc, TLI.getRegClassFor(RetVT), Op0, Op0IsKill, ImmR,
ImmS);
}
unsigned Opc, ImmS;
switch (RetVT.SimpleTy) {
default: return 0;
- case MVT::i8:
- case MVT::i16:
- case MVT::i32:
- RetVT = MVT::i32;
- Opc = AArch64::UBFMWri; ImmS = 31; break;
- case MVT::i64:
- Opc = AArch64::UBFMXri; ImmS = 63; break;
+ case MVT::i8: Opc = AArch64::UBFMWri; ImmS = 7; break;
+ case MVT::i16: Opc = AArch64::UBFMWri; ImmS = 15; break;
+ case MVT::i32: Opc = AArch64::UBFMWri; ImmS = 31; break;
+ case MVT::i64: Opc = AArch64::UBFMXri; ImmS = 63; break;
}
+ RetVT.SimpleTy = std::max(MVT::i32, RetVT.SimpleTy);
return FastEmitInst_rii(Opc, TLI.getRegClassFor(RetVT), Op0, Op0IsKill, Shift,
ImmS);
}
unsigned Opc, ImmS;
switch (RetVT.SimpleTy) {
default: return 0;
- case MVT::i8:
- case MVT::i16:
- case MVT::i32:
- RetVT = MVT::i32;
- Opc = AArch64::SBFMWri; ImmS = 31; break;
- case MVT::i64:
- Opc = AArch64::SBFMXri; ImmS = 63; break;
+ case MVT::i8: Opc = AArch64::SBFMWri; ImmS = 7; break;
+ case MVT::i16: Opc = AArch64::SBFMWri; ImmS = 15; break;
+ case MVT::i32: Opc = AArch64::SBFMWri; ImmS = 31; break;
+ case MVT::i64: Opc = AArch64::SBFMXri; ImmS = 63; break;
}
+ RetVT.SimpleTy = std::max(MVT::i32, RetVT.SimpleTy);
return FastEmitInst_rii(Opc, TLI.getRegClassFor(RetVT), Op0, Op0IsKill, Shift,
ImmS);
}
; RUN: llc -fast-isel -fast-isel-abort -mtriple=arm64-apple-darwin < %s | FileCheck %s
; CHECK-LABEL: lsl_i8
-; CHECK: lsl {{w[0-9]*}}, {{w[0-9]*}}, #4
+; CHECK: ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
define zeroext i8 @lsl_i8(i8 %a) {
%1 = shl i8 %a, 4
ret i8 %1
}
; CHECK-LABEL: lsl_i16
-; CHECK: lsl {{w[0-9]*}}, {{w[0-9]*}}, #8
+; CHECK: ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #8, #8
define zeroext i16 @lsl_i16(i16 %a) {
%1 = shl i16 %a, 8
ret i16 %1
}
; CHECK-LABEL: lsr_i8
-; CHECK: lsr {{w[0-9]*}}, {{w[0-9]*}}, #4
+; CHECK: ubfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
define zeroext i8 @lsr_i8(i8 %a) {
%1 = lshr i8 %a, 4
ret i8 %1
}
; CHECK-LABEL: lsr_i16
-; CHECK: lsr {{w[0-9]*}}, {{w[0-9]*}}, #8
+; CHECK: ubfx {{w[0-9]*}}, {{w[0-9]*}}, #8, #8
define zeroext i16 @lsr_i16(i16 %a) {
%1 = lshr i16 %a, 8
ret i16 %1
}
; CHECK-LABEL: asr_i8
-; CHECK: asr {{w[0-9]*}}, {{w[0-9]*}}, #4
+; CHECK: sbfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
define zeroext i8 @asr_i8(i8 %a) {
%1 = ashr i8 %a, 4
ret i8 %1
}
; CHECK-LABEL: asr_i16
-; CHECK: asr {{w[0-9]*}}, {{w[0-9]*}}, #8
+; CHECK: sbfx {{w[0-9]*}}, {{w[0-9]*}}, #8, #8
define zeroext i16 @asr_i16(i16 %a) {
%1 = ashr i16 %a, 8
ret i16 %1
ret i64 %1
}
+; CHECK-LABEL: shift_test1
+; CHECK: ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
+; CHECK-NEXT: sbfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
+define i32 @shift_test1(i8 %a) {
+ %1 = shl i8 %a, 4
+ %2 = ashr i8 %1, 4
+ %3 = sext i8 %2 to i32
+ ret i32 %3
+}
+