[WebAssembly] Disable folding of GA+reg into load/store constant offsets
Summary:
If the register has a negative value then unsigned overflow will occur;
this case is sometimes even created intentionally by LSR. For now
disable GA+reg folding. Fixes PR29127
Differential Revision: https://reviews.llvm.org/D24053
llvm-svn: 280285
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
index 521c664..5bd09bd 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
@@ -41,15 +41,13 @@
}]>;
// GlobalAddresses are conceptually unsigned values, so we can also fold them
-// into immediate values as long as their offsets are non-negative.
+// into immediate values as long as the add is 'nuw'.
+// TODO: We'd like to also match GA offsets but there are cases where the
+// register can have a negative value. Find out what more we can do.
def regPlusGA : PatFrag<(ops node:$addr, node:$off),
(add node:$addr, node:$off),
[{
- return N->getFlags()->hasNoUnsignedWrap() ||
- (N->getOperand(1)->getOpcode() == WebAssemblyISD::Wrapper &&
- isa<GlobalAddressSDNode>(N->getOperand(1)->getOperand(0)) &&
- cast<GlobalAddressSDNode>(N->getOperand(1)->getOperand(0))
- ->getOffset() >= 0);
+ return N->getFlags()->hasNoUnsignedWrap();
}]>;
// We don't need a regPlusES because external symbols never have constant