aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2015-12-15 22:01:29 +0000
committerDan Gohman <dan433584@gmail.com>2015-12-15 22:01:29 +0000
commit4b9d7916eed5f1c7e24c46a7ec2860237fb0ee7a (patch)
tree617340a17bdbf083ce995db41c55536c919916ba /llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
parent38b9a32fcd2c90005f82934da8169bbc7f37db0e (diff)
downloadllvm-4b9d7916eed5f1c7e24c46a7ec2860237fb0ee7a.zip
llvm-4b9d7916eed5f1c7e24c46a7ec2860237fb0ee7a.tar.gz
llvm-4b9d7916eed5f1c7e24c46a7ec2860237fb0ee7a.tar.bz2
[WebAssembly] Implement instruction selection for constant offsets in addresses.
Add instruction patterns for matching load and store instructions with constant offsets in addresses. The code is fairly redundant due to the need to replicate everything between imm, tglobaldadr, and texternalsym, but this appears to be common tablegen practice. The main alternative appears to be to introduce matching functions with C++ code, but sticking with purely generated matchers seems better for now. Also note that this doesn't yet support offsets from getelementptr, which will be the most common case; that will depend on a change in target-independent code in order to set the NoUnsignedWrap flag, which I'll submit separately. Until then, the testcase uses ptrtoint+add+inttoptr with a nuw on the add. Also implement isLegalAddressingMode with an approximation of this. Differential Revision: http://reviews.llvm.org/D15538 llvm-svn: 255681
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index a5ca08f..597d6f4 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -261,6 +261,24 @@ bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz() const {
return true;
}
+bool WebAssemblyTargetLowering::isLegalAddressingMode(const DataLayout &DL,
+ const AddrMode &AM,
+ Type *Ty,
+ unsigned AS) const {
+ // WebAssembly offsets are added as unsigned without wrapping. The
+ // isLegalAddressingMode gives us no way to determine if wrapping could be
+ // happening, so we approximate this by accepting only non-negative offsets.
+ if (AM.BaseOffs < 0)
+ return false;
+
+ // WebAssembly has no scale register operands.
+ if (AM.Scale != 0)
+ return false;
+
+ // Everything else is legal.
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// WebAssembly Lowering private implementation.
//===----------------------------------------------------------------------===//
@@ -408,7 +426,8 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
if (In.Flags.isInConsecutiveRegs())
fail(DL, DAG, "WebAssembly hasn't implemented cons regs return values");
if (In.Flags.isInConsecutiveRegsLast())
- fail(DL, DAG, "WebAssembly hasn't implemented cons regs last return values");
+ fail(DL, DAG,
+ "WebAssembly hasn't implemented cons regs last return values");
// Ignore In.getOrigAlign() because all our arguments are passed in
// registers.
Tys.push_back(In.VT);
@@ -551,9 +570,9 @@ SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
assert(GA->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
if (GA->getAddressSpace() != 0)
fail(DL, DAG, "WebAssembly only expects the 0 address space");
- return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
- DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
- GA->getOffset()));
+ return DAG.getNode(
+ WebAssemblyISD::Wrapper, DL, VT,
+ DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset()));
}
SDValue