[llvm] r296811 - [PPC] Fix code generation for bswap(int32) followed by store16

Guozhi Wei via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 2 13:08:00 PST 2017


Author: carrot
Date: Thu Mar  2 15:07:59 2017
New Revision: 296811

URL: http://llvm.org/viewvc/llvm-project?rev=296811&view=rev
Log:
[PPC] Fix code generation for bswap(int32) followed by store16

This patch fixes pr32063.

Current code in PPCTargetLowering::PerformDAGCombine can transform

bswap
store

into a single PPCISD::STBRX instruction. but it doesn't consider the case that the operand size of bswap may be larger than store size. When it occurs, we need 2 modifications,

1 For the last operand of PPCISD::STBRX, we should not use DAG.getValueType(N->getOperand(1).getValueType()), instead we should use cast<StoreSDNode>(N)->getMemoryVT().

2 Before PPCISD::STBRX, we need to shift the original operand of bswap to the right side.

Differential Revision: https://reviews.llvm.org/D30362


Added:
    llvm/trunk/test/CodeGen/PowerPC/pr32063.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=296811&r1=296810&r2=296811&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Thu Mar  2 15:07:59 2017
@@ -11391,9 +11391,17 @@ SDValue PPCTargetLowering::PerformDAGCom
       if (BSwapOp.getValueType() == MVT::i16)
         BSwapOp = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, BSwapOp);
 
+      // If the type of BSWAP operand is wider than stored memory width
+      // it need to be shifted to the right side before STBRX.
+      EVT mVT = cast<StoreSDNode>(N)->getMemoryVT();
+      if (Op1VT.bitsGT(mVT)) {
+        int shift = Op1VT.getSizeInBits() - mVT.getSizeInBits();
+        BSwapOp = DAG.getNode(ISD::SRL, dl, Op1VT, BSwapOp,
+                              DAG.getConstant(shift, dl, MVT::i32));
+      }
+
       SDValue Ops[] = {
-        N->getOperand(0), BSwapOp, N->getOperand(2),
-        DAG.getValueType(N->getOperand(1).getValueType())
+        N->getOperand(0), BSwapOp, N->getOperand(2), DAG.getValueType(mVT)
       };
       return
         DAG.getMemIntrinsicNode(PPCISD::STBRX, dl, DAG.getVTList(MVT::Other),

Added: llvm/trunk/test/CodeGen/PowerPC/pr32063.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/pr32063.ll?rev=296811&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/pr32063.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/pr32063.ll Thu Mar  2 15:07:59 2017
@@ -0,0 +1,16 @@
+; RUN: llc -O2 < %s | FileCheck %s
+target triple = "powerpc64le-linux-gnu"
+
+define void @foo(i32 %v, i16* %p) {
+        %1 = and i32 %v, -65536
+        %2 = tail call i32 @llvm.bswap.i32(i32 %1)
+        %conv = trunc i32 %2 to i16
+        store i16 %conv, i16* %p
+        ret void
+
+; CHECK:     srwi
+; CHECK:     sthbrx
+; CHECK-NOT: stwbrx
+}
+
+declare i32 @llvm.bswap.i32(i32)




More information about the llvm-commits mailing list