[PATCH] D30362: [PPC] Fix code generation for bswap(int32) followed by store16

Guozhi Wei via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 24 16:10:29 PST 2017


Carrot created this revision.
Herald added subscribers: nemanjai, mehdi_amini.

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.


https://reviews.llvm.org/D30362

Files:
  lib/Target/PowerPC/PPCISelLowering.cpp
  test/CodeGen/PowerPC/pr32063.ll


Index: test/CodeGen/PowerPC/pr32063.ll
===================================================================
--- test/CodeGen/PowerPC/pr32063.ll
+++ test/CodeGen/PowerPC/pr32063.ll
@@ -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)
Index: lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- lib/Target/PowerPC/PPCISelLowering.cpp
+++ lib/Target/PowerPC/PPCISelLowering.cpp
@@ -11353,9 +11353,17 @@
       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),


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30362.89743.patch
Type: text/x-patch
Size: 1682 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170225/983526b2/attachment.bin>


More information about the llvm-commits mailing list