summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSilviu Baranga <silviu.baranga@arm.com>2016-05-09 11:10:44 +0000
committerSilviu Baranga <silviu.baranga@arm.com>2016-05-09 11:10:44 +0000
commitf60be28ed83473983bae52ca95b34b05a6b992ed (patch)
tree076157a42fc863a4cfd5cc35d62160f70aab0d35 /llvm/lib
parentb8d8c62b341ab7a294231e6395dede2190bb93a8 (diff)
downloadbcm5719-llvm-f60be28ed83473983bae52ca95b34b05a6b992ed.tar.gz
bcm5719-llvm-f60be28ed83473983bae52ca95b34b05a6b992ed.zip
[AArch64] Implement lowering of the X constraint on AArch64
Summary: This implements the lowering of the X constraint on AArch64. The default behaviour of the X constraint lowering is to restrict it to "f". This is a problem because the "f" constraint is not implemented on AArch64 and would be too restrictive anyway. Therefore, the AArch64 hook will lower this to "w" (if the operand is a floating point or vector) or "r" otherwise. The implementation is similar with the one added for ARM (r267411). This is the AArch64 side of the fix for http://llvm.org/PR26493 Reviewers: rengolin Subscribers: aemerson, rengolin, llvm-commits, t.p.northover Differential Revision: http://reviews.llvm.org/D19967 llvm-svn: 268907
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp21
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.h3
2 files changed, 24 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 575f9d9fa5b..5b4516b36fb 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -4687,6 +4687,27 @@ SDValue AArch64TargetLowering::getRsqrtEstimate(SDValue Operand,
// is prefixed by the %w modifier. Floating-point and SIMD register operands
// will be output with the v prefix unless prefixed by the %b, %h, %s, %d or
// %q modifier.
+const char *AArch64TargetLowering::LowerXConstraint(EVT ConstraintVT) const {
+ // At this point, we have to lower this constraint to something else, so we
+ // lower it to an "r" or "w". However, by doing this we will force the result
+ // to be in register, while the X constraint is much more permissive.
+ //
+ // Although we are correct (we are free to emit anything, without
+ // constraints), we might break use cases that would expect us to be more
+ // efficient and emit something else.
+ if (!Subtarget->hasFPARMv8())
+ return "r";
+
+ if (ConstraintVT.isFloatingPoint())
+ return "w";
+
+ if (ConstraintVT.isVector() &&
+ (ConstraintVT.getSizeInBits() == 64 ||
+ ConstraintVT.getSizeInBits() == 128))
+ return "w";
+
+ return "r";
+}
/// getConstraintType - Given a constraint letter, return the type of
/// constraint it is for this target.
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 65e2614461d..ea2b8c1904f 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -535,6 +535,9 @@ private:
std::pair<unsigned, const TargetRegisterClass *>
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
StringRef Constraint, MVT VT) const override;
+
+ const char *LowerXConstraint(EVT ConstraintVT) const override;
+
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const override;
OpenPOWER on IntegriCloud