forked from OSchip/llvm-project
[InstCombine] reduce funnel-shift i16 X, X, 8 to bswap X
Prefer the more exact intrinsic to remove a use of the input value and possibly make further transforms easier (we will still need to match patterns with funnel-shift of wider types as pieces of bswap, especially if we want to canonicalize to funnel-shift with constant shift amount). Discussed in D46760. llvm-svn: 364187
This commit is contained in:
parent
5dbd9228c4
commit
89efefb170
|
@ -1983,6 +1983,13 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||
if (match(Op0, m_ZeroInt()) || match(Op0, m_Undef()))
|
||||
return BinaryOperator::CreateLShr(Op1,
|
||||
ConstantExpr::getSub(WidthC, ShAmtC));
|
||||
|
||||
// fshl i16 X, X, 8 --> bswap i16 X (reduce to more-specific form)
|
||||
if (Op0 == Op1 && BitWidth == 16 && match(ShAmtC, m_SpecificInt(8))) {
|
||||
Module *Mod = II->getModule();
|
||||
Function *Bswap = Intrinsic::getDeclaration(Mod, Intrinsic::bswap, Ty);
|
||||
return CallInst::Create(Bswap, { Op0 });
|
||||
}
|
||||
}
|
||||
|
||||
// Left or right might be masked.
|
||||
|
|
|
@ -544,7 +544,7 @@ declare <3 x i16> @llvm.fshl.v3i16(<3 x i16>, <3 x i16>, <3 x i16>)
|
|||
|
||||
define i16 @fshl_bswap(i16 %x) {
|
||||
; CHECK-LABEL: @fshl_bswap(
|
||||
; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 8)
|
||||
; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])
|
||||
; CHECK-NEXT: ret i16 [[R]]
|
||||
;
|
||||
%r = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 8)
|
||||
|
@ -553,7 +553,7 @@ define i16 @fshl_bswap(i16 %x) {
|
|||
|
||||
define i16 @fshr_bswap(i16 %x) {
|
||||
; CHECK-LABEL: @fshr_bswap(
|
||||
; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 8)
|
||||
; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])
|
||||
; CHECK-NEXT: ret i16 [[R]]
|
||||
;
|
||||
%r = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 8)
|
||||
|
@ -562,13 +562,15 @@ define i16 @fshr_bswap(i16 %x) {
|
|||
|
||||
define <3 x i16> @fshl_bswap_vector(<3 x i16> %x) {
|
||||
; CHECK-LABEL: @fshl_bswap_vector(
|
||||
; CHECK-NEXT: [[R:%.*]] = call <3 x i16> @llvm.fshl.v3i16(<3 x i16> [[X:%.*]], <3 x i16> [[X]], <3 x i16> <i16 8, i16 8, i16 8>)
|
||||
; CHECK-NEXT: [[R:%.*]] = call <3 x i16> @llvm.bswap.v3i16(<3 x i16> [[X:%.*]])
|
||||
; CHECK-NEXT: ret <3 x i16> [[R]]
|
||||
;
|
||||
%r = call <3 x i16> @llvm.fshl.v3i16(<3 x i16> %x, <3 x i16> %x, <3 x i16> <i16 8, i16 8, i16 8>)
|
||||
ret <3 x i16> %r
|
||||
}
|
||||
|
||||
; Negative test
|
||||
|
||||
define i16 @fshl_bswap_wrong_op(i16 %x, i16 %y) {
|
||||
; CHECK-LABEL: @fshl_bswap_wrong_op(
|
||||
; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[Y:%.*]], i16 8)
|
||||
|
@ -578,6 +580,8 @@ define i16 @fshl_bswap_wrong_op(i16 %x, i16 %y) {
|
|||
ret i16 %r
|
||||
}
|
||||
|
||||
; Negative test
|
||||
|
||||
define i16 @fshr_bswap_wrong_amount(i16 %x) {
|
||||
; CHECK-LABEL: @fshr_bswap_wrong_amount(
|
||||
; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 12)
|
||||
|
@ -587,6 +591,8 @@ define i16 @fshr_bswap_wrong_amount(i16 %x) {
|
|||
ret i16 %r
|
||||
}
|
||||
|
||||
; Negative test
|
||||
|
||||
define i32 @fshl_bswap_wrong_width(i32 %x) {
|
||||
; CHECK-LABEL: @fshl_bswap_wrong_width(
|
||||
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 8)
|
||||
|
|
Loading…
Reference in New Issue