From 5507b53e8d0f4ffa0b7d639715200be0f0af509d Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 3 Jul 2017 05:54:15 +0000 Subject: [PATCH] [InstCombine] Support BITWISE_OP( BSWAP(x), CONSTANT ) -> BSWAP( BITWISE_OP(x, BSWAP(CONSTANT) ) ) for splat vectors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307002 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 30 +++++++++------------- test/Transforms/InstCombine/bswap-fold.ll | 12 ++++----- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 5a73eb5cc2f..0f034107b3d 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -82,27 +82,21 @@ static Value *getFCmpValue(unsigned Code, Value *LHS, Value *RHS, Value *InstCombiner::SimplifyBSwap(BinaryOperator &I) { assert(I.isBitwiseLogicOp() && "Unexpected opcode for bswap simplifying"); - // TODO handle constant on one side with vectors. - Value *OldLHS = I.getOperand(0); - Value *OldRHS = I.getOperand(1); - ConstantInt *ConstRHS = dyn_cast(OldRHS); - IntrinsicInst *IntrLHS = dyn_cast(OldLHS); - IntrinsicInst *IntrRHS = dyn_cast(OldRHS); - bool IsBswapLHS = (IntrLHS && IntrLHS->getIntrinsicID() == Intrinsic::bswap); - bool IsBswapRHS = (IntrRHS && IntrRHS->getIntrinsicID() == Intrinsic::bswap); - - if (!IsBswapLHS) + Value *NewLHS; + if (!match(I.getOperand(0), m_BSwap(m_Value(NewLHS)))) return nullptr; - if (!IsBswapRHS && !ConstRHS) - return nullptr; - - /// OP( BSWAP(x), BSWAP(y) ) -> BSWAP( OP(x, y) ) - /// OP( BSWAP(x), CONSTANT ) -> BSWAP( OP(x, BSWAP(CONSTANT) ) ) - Value *NewLHS = IntrLHS->getOperand(0); + Value *NewRHS; + const APInt *C; - Value *NewRHS = IsBswapRHS ? IntrRHS->getOperand(0) : - Builder->getInt(ConstRHS->getValue().byteSwap()); + if (match(I.getOperand(1), m_BSwap(m_Value(NewRHS)))) { + // OP( BSWAP(x), BSWAP(y) ) -> BSWAP( OP(x, y) ) + // NewRHS initialized by the matcher. + } else if (match(I.getOperand(1), m_APInt(C))) { + // OP( BSWAP(x), CONSTANT ) -> BSWAP( OP(x, BSWAP(CONSTANT) ) ) + NewRHS = ConstantInt::get(I.getType(), C->byteSwap()); + } else + return nullptr; Value *BinOp = Builder->CreateBinOp(I.getOpcode(), NewLHS, NewRHS); Function *F = Intrinsic::getDeclaration(I.getModule(), Intrinsic::bswap, diff --git a/test/Transforms/InstCombine/bswap-fold.ll b/test/Transforms/InstCombine/bswap-fold.ll index 64e80c1b29e..845e0eab3fa 100644 --- a/test/Transforms/InstCombine/bswap-fold.ll +++ b/test/Transforms/InstCombine/bswap-fold.ll @@ -249,8 +249,8 @@ define <2 x i32> @bs_xor32vec(<2 x i32> %a, <2 x i32> %b) #0 { define <2 x i32> @bs_and32ivec(<2 x i32> %a, <2 x i32> %b) #0 { ; CHECK-LABEL: @bs_and32ivec( -; CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[A:%.*]]) -; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[TMP1]]) ; CHECK-NEXT: ret <2 x i32> [[TMP2]] ; %tmp1 = tail call <2 x i32> @llvm.bswap.v2i32(<2 x i32> %a) @@ -260,8 +260,8 @@ define <2 x i32> @bs_and32ivec(<2 x i32> %a, <2 x i32> %b) #0 { define <2 x i32> @bs_or32ivec(<2 x i32> %a, <2 x i32> %b) #0 { ; CHECK-LABEL: @bs_or32ivec( -; CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[A:%.*]]) -; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], +; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[TMP1]]) ; CHECK-NEXT: ret <2 x i32> [[TMP2]] ; %tmp1 = tail call <2 x i32> @llvm.bswap.v2i32(<2 x i32> %a) @@ -271,8 +271,8 @@ define <2 x i32> @bs_or32ivec(<2 x i32> %a, <2 x i32> %b) #0 { define <2 x i32> @bs_xor32ivec(<2 x i32> %a, <2 x i32> %b) #0 { ; CHECK-LABEL: @bs_xor32ivec( -; CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[A:%.*]]) -; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], +; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[A:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[TMP1]]) ; CHECK-NEXT: ret <2 x i32> [[TMP2]] ; %tmp1 = tail call <2 x i32> @llvm.bswap.v2i32(<2 x i32> %a) -- 2.11.0