summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2016-01-20 23:16:59 +0000
committerDan Gohman <dan433584@gmail.com>2016-01-20 23:16:59 +0000
commit760bef5e508c985bf9216d81adfc20a657d77611 (patch)
tree3e2b0d38f819e7f1b5ad416b249034203f07697c
parent10badfc924871e020981a12705dcec9544912278 (diff)
downloadbcm5719-llvm-760bef5e508c985bf9216d81adfc20a657d77611.tar.gz
bcm5719-llvm-760bef5e508c985bf9216d81adfc20a657d77611.zip
[SelectionDAG] Fix constant offset folding to avoid commuting non-commutative operators.
This fixes a miscompile in MultiSource/Benchmarks/MiBench/consumer-lame introduced in r258296. llvm-svn: 258366
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp5
-rw-r--r--llvm/test/CodeGen/X86/negative-offset.ll18
2 files changed, 21 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 33863f41732..1cd5cd8ac23 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -3312,8 +3312,9 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, SDLoc DL, EVT VT,
// fold (add Sym, c) -> Sym+c
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Cst1))
return FoldSymbolOffset(Opcode, VT, GA, Cst2);
- if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Cst2))
- return FoldSymbolOffset(Opcode, VT, GA, Cst1);
+ if (isCommutativeBinOp(Opcode))
+ if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Cst2))
+ return FoldSymbolOffset(Opcode, VT, GA, Cst1);
// For vectors extract each constant element into Inputs so we can constant
// fold them individually.
diff --git a/llvm/test/CodeGen/X86/negative-offset.ll b/llvm/test/CodeGen/X86/negative-offset.ll
new file mode 100644
index 00000000000..dc1b255d020
--- /dev/null
+++ b/llvm/test/CodeGen/X86/negative-offset.ll
@@ -0,0 +1,18 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Test that a constant consisting of a global symbol with a negative offset
+; is properly folded and isel'd.
+
+; CHECK-LABEL: negative_offset:
+; CHECK: movl $G, %eax
+; CHECK: notq %rax
+; CHECK: addq %rdi, %rax
+; CHECK: retq
+@G = external global [8 x i32]
+define i8* @negative_offset(i8* %a) {
+ %t = getelementptr i8, i8* %a, i64 sub (i64 -1, i64 ptrtoint ([8 x i32]* @G to i64))
+ ret i8* %t
+}
OpenPOWER on IntegriCloud