[llvm] r318436 - [PPC] Change i32 constant in store instruction to i64

Guozhi Wei via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 16 10:27:34 PST 2017


Author: carrot
Date: Thu Nov 16 10:27:34 2017
New Revision: 318436

URL: http://llvm.org/viewvc/llvm-project?rev=318436&view=rev
Log:
[PPC] Change i32 constant in store instruction to i64

This patch changes all i32 constant in store instruction to i64 with truncation, to increase the chance that the referenced constant can be shared with other i64 constant.

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


Added:
    llvm/trunk/test/CodeGen/PowerPC/store-constant.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=318436&r1=318435&r2=318436&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Nov 16 10:27:34 2017
@@ -2015,6 +2015,9 @@ public:
   /// For integers this is the same as doing a TRUNCATE and storing the result.
   /// For floats, it is the same as doing an FP_ROUND and storing the result.
   bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
+  void setTruncatingStore(bool Truncating) {
+    StoreSDNodeBits.IsTruncating = Truncating;
+  }
 
   const SDValue &getValue() const { return getOperand(1); }
   const SDValue &getBasePtr() const { return getOperand(2); }

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=318436&r1=318435&r2=318436&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Thu Nov 16 10:27:34 2017
@@ -12223,9 +12223,24 @@ SDValue PPCTargetLowering::PerformDAGCom
                                 cast<StoreSDNode>(N)->getMemOperand());
     }
 
+    // STORE Constant:i32<0>  ->  STORE<trunc to i32> Constant:i64<0>
+    // So it can increase the chance of CSE constant construction.
+    EVT VT = N->getOperand(1).getValueType();
+    if (Subtarget.isPPC64() && !DCI.isBeforeLegalize() &&
+        isa<ConstantSDNode>(N->getOperand(1)) && VT == MVT::i32) {
+      SDValue Const64 = DAG.getConstant(N->getConstantOperandVal(1), dl,
+                                        MVT::i64);
+      // DAG.getTruncStore() can't be used here because it doesn't accept
+      // the general (base + offset) addressing mode.
+      // So we use UpdateNodeOperands and setTruncatingStore instead.
+      DAG.UpdateNodeOperands(N, N->getOperand(0), Const64, N->getOperand(2),
+                             N->getOperand(3));
+      cast<StoreSDNode>(N)->setTruncatingStore(true);
+      return SDValue(N, 0);
+    }
+
     // For little endian, VSX stores require generating xxswapd/lxvd2x.
     // Not needed on ISA 3.0 based CPUs since we have a non-permuting store.
-    EVT VT = N->getOperand(1).getValueType();
     if (VT.isSimple()) {
       MVT StoreVT = VT.getSimpleVT();
       if (Subtarget.needsSwapsForVSXMemOps() &&

Added: llvm/trunk/test/CodeGen/PowerPC/store-constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/store-constant.ll?rev=318436&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/store-constant.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/store-constant.ll Thu Nov 16 10:27:34 2017
@@ -0,0 +1,44 @@
+; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -verify-machineinstrs | FileCheck %s
+
+; Test the same constant can be used by different stores.
+
+%struct.S = type { i64, i8, i16, i32 }
+
+define void @foo(%struct.S* %p) {
+  %l4 = bitcast %struct.S* %p to i64*
+  store i64 0, i64* %l4, align 8
+  %c = getelementptr %struct.S, %struct.S* %p, i64 0, i32 1
+  store i8 0, i8* %c, align 8
+  %s = getelementptr %struct.S, %struct.S* %p, i64 0, i32 2
+  store i16 0, i16* %s, align 2
+  %i = getelementptr %struct.S, %struct.S* %p, i64 0, i32 3
+  store i32 0, i32* %i, align 4
+  ret void
+
+; CHECK-LABEL: @foo
+; CHECK:       li 4, 0
+; CHECK:       stb 4, 8(3)
+; CHECK:       std 4, 0(3)
+; CHECK:       sth 4, 10(3)
+; CHECK:       stw 4, 12(3)
+}
+
+define void @bar(%struct.S* %p) {
+  %i = getelementptr %struct.S, %struct.S* %p, i64 0, i32 3
+  store i32 2, i32* %i, align 4
+  %s = getelementptr %struct.S, %struct.S* %p, i64 0, i32 2
+  store i16 2, i16* %s, align 2
+  %c = getelementptr %struct.S, %struct.S* %p, i64 0, i32 1
+  store i8 2, i8* %c, align 8
+  %l4 = bitcast %struct.S* %p to i64*
+  store i64 2, i64* %l4, align 8
+  ret void
+
+; CHECK-LABEL: @bar
+; CHECK:       li 4, 2
+; CHECK:       stw 4, 12(3)
+; CHECK:       sth 4, 10(3)
+; CHECK:       std 4, 0(3)
+; CHECK:       stb 4, 8(3)
+}
+




More information about the llvm-commits mailing list