aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@imgtec.com>2016-09-06 12:36:24 +0000
committerSimon Dardis <simon.dardis@imgtec.com>2016-09-06 12:36:24 +0000
commitb432a3ed7ee0a6b23e47a0d359ff00b0e84ac131 (patch)
tree5c94e07d8305042ee2cefacaeb050bbbe35fde88
parent020ec299bff6dbc9a4f8dd1d19e09a3f26441f30 (diff)
downloadllvm-b432a3ed7ee0a6b23e47a0d359ff00b0e84ac131.zip
llvm-b432a3ed7ee0a6b23e47a0d359ff00b0e84ac131.tar.gz
llvm-b432a3ed7ee0a6b23e47a0d359ff00b0e84ac131.tar.bz2
[mips] Tighten FastISel restrictions
LLVM PR/29052 highlighted that FastISel for MIPS attempted to lower arguments assuming that it was using the paired 32bit registers to perform operations for f64. This mode of operation is not supported for MIPSR6. This patch resolves the reported issue by adding additional checks for unsupported floating point unit configuration. Thanks to mike.k for reporting this issue! Reviewers: seanbruno, vkalintiris Differential Review: https://reviews.llvm.org/D23795 llvm-svn: 280706
-rw-r--r--llvm/lib/Target/Mips/MipsFastISel.cpp18
-rw-r--r--llvm/test/CodeGen/Mips/Fast-ISel/double-arg.ll14
2 files changed, 31 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp
index e7b1139..9453164 100644
--- a/llvm/lib/Target/Mips/MipsFastISel.cpp
+++ b/llvm/lib/Target/Mips/MipsFastISel.cpp
@@ -976,9 +976,13 @@ bool MipsFastISel::selectFPExt(const Instruction *I) {
bool MipsFastISel::selectSelect(const Instruction *I) {
assert(isa<SelectInst>(I) && "Expected a select instruction.");
+ DEBUG(dbgs() << "selectSelect\n");
+
MVT VT;
- if (!isTypeSupported(I->getType(), VT))
+ if (!isTypeSupported(I->getType(), VT) || UnsupportedFPMode) {
+ DEBUG(dbgs() << ".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
return false;
+ }
unsigned CondMovOpc;
const TargetRegisterClass *RC;
@@ -1376,6 +1380,10 @@ bool MipsFastISel::fastLowerArguments() {
break;
case MVT::f64:
+ if (UnsupportedFPMode) {
+ DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode\n");
+ return false;
+ }
if (NextAFGR64 == AFGR64ArgRegs.end()) {
DEBUG(dbgs() << ".. .. gave up (ran out of AFGR64 arguments)\n");
return false;
@@ -1617,6 +1625,8 @@ bool MipsFastISel::selectRet(const Instruction *I) {
const Function &F = *I->getParent()->getParent();
const ReturnInst *Ret = cast<ReturnInst>(I);
+ DEBUG(dbgs() << "selectRet\n");
+
if (!FuncInfo.CanLowerReturn)
return false;
@@ -1677,6 +1687,12 @@ bool MipsFastISel::selectRet(const Instruction *I) {
if (RVVT == MVT::f128)
return false;
+ // Do not handle FGR64 returns for now.
+ if (RVVT == MVT::f64 && UnsupportedFPMode) {
+ DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode\n");
+ return false;
+ }
+
MVT DestVT = VA.getValVT();
// Special handling for extended integers.
if (RVVT != DestVT) {
diff --git a/llvm/test/CodeGen/Mips/Fast-ISel/double-arg.ll b/llvm/test/CodeGen/Mips/Fast-ISel/double-arg.ll
new file mode 100644
index 0000000..ee77d43
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/Fast-ISel/double-arg.ll
@@ -0,0 +1,14 @@
+; RUN: not llc -march=mipsel -mcpu=mips32r2 -fast-isel -mattr=+fp64 < %s \
+; RUN: -fast-isel-abort=3
+
+; Check that FastISel aborts when we have 64bit FPU registers. FastISel currently
+; supports AFGR64 only, which uses paired 32 bit registers.
+
+define zeroext i1 @f(double %value) {
+entry:
+; CHECK-LABEL: f:
+; CHECK: sdc1
+ %value.addr = alloca double, align 8
+ store double %value, double* %value.addr, align 8
+ ret i1 false
+}