[PowerPC] PR19796: Also match ISD::TargetConstant in isIntS16Immediate
authorAdam Nemet <anemet@apple.com>
Tue, 20 May 2014 17:20:34 +0000 (17:20 +0000)
committerAdam Nemet <anemet@apple.com>
Tue, 20 May 2014 17:20:34 +0000 (17:20 +0000)
The SplitIndexingFromLoad changes exposed a latent isel bug in the PowerPC64
backend.  We matched an immediate offset with STWX8 even though it only
supports register offset.

The culprit is the complex-pattern predicate, SelectAddrIdx, which decides
that if the offset is not ISD::Constant it must be a register.

Many thanks to Bill Schmidt for testing this.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209219 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelLowering.cpp
test/CodeGen/PowerPC/indexed-load.ll [new file with mode: 0644]

index 04bd43547c746e21fe403208db4b43a16f2a9b56..214c86920609eb25f50db74341b9a8a3ade7b054 100644 (file)
@@ -1137,7 +1137,7 @@ SDValue PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
 /// sign extension from a 16-bit value.  If so, this returns true and the
 /// immediate.
 static bool isIntS16Immediate(SDNode *N, short &Imm) {
-  if (N->getOpcode() != ISD::Constant)
+  if (!isa<ConstantSDNode>(N))
     return false;
 
   Imm = (short)cast<ConstantSDNode>(N)->getZExtValue();
diff --git a/test/CodeGen/PowerPC/indexed-load.ll b/test/CodeGen/PowerPC/indexed-load.ll
new file mode 100644 (file)
index 0000000..59fc058
--- /dev/null
@@ -0,0 +1,22 @@
+; RUN: llc < %s | FileCheck %s
+
+; The SplitIndexingFromLoad tranformation exposed an isel backend bug.  This
+; testcase used to generate stwx 4, 3, 64.  stwx does not have an
+; immediate-offset format (note the 64) and it should not be matched.
+
+target datalayout = "e-m:e-i64:64-n32:64"
+target triple = "powerpc64le-unknown-linux-gnu"
+
+%class.test = type { [64 x i8], [5 x i8] }
+
+; CHECK-LABEL: f:
+; CHECK-NOT: stwx {{[0-9]+}}, {{[0-9]+}}, 64
+define void @f(%class.test* %this) {
+entry:
+  %Subminor.i.i = getelementptr inbounds %class.test* %this, i64 0, i32 1
+  %0 = bitcast [5 x i8]* %Subminor.i.i to i40*
+  %bf.load2.i.i = load i40* %0, align 4
+  %bf.clear7.i.i = and i40 %bf.load2.i.i, -8589934592
+  store i40 %bf.clear7.i.i, i40* %0, align 4
+  ret void
+}