From: Sanjay Patel Date: Mon, 24 Jun 2019 15:20:49 +0000 (+0000) Subject: [InstCombine] reduce funnel-shift i16 X, X, 8 to bswap X X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0eaa3a2c7c3141022e44e83463d1f8bef4175f58;p=llvm [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364187 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 1b247245c4c..63f313e1f7f 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -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. diff --git a/test/Transforms/InstCombine/fsh.ll b/test/Transforms/InstCombine/fsh.ll index 92be6d3795d..4300f041773 100644 --- a/test/Transforms/InstCombine/fsh.ll +++ b/test/Transforms/InstCombine/fsh.ll @@ -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> ) +; 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> ) 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)