[llvm] r296031 - ARM: make sure FastISel bails on f64 operations for Cortex-M4.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 23 14:35:00 PST 2017
Author: tnorthover
Date: Thu Feb 23 16:35:00 2017
New Revision: 296031
URL: http://llvm.org/viewvc/llvm-project?rev=296031&view=rev
Log:
ARM: make sure FastISel bails on f64 operations for Cortex-M4.
FastISel wasn't checking the isFPOnlySP subtarget feature before emitting
double-precision operations, so it got completely invalid CodeGen for doubles
on Cortex-M4F.
The normal ISel testing wasn't spectacular either so I added a second RUN line
to improve that while I was in the area.
Added:
llvm/trunk/test/CodeGen/ARM/fp-only-sp.ll
Modified:
llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=296031&r1=296030&r2=296031&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Thu Feb 23 16:35:00 2017
@@ -1350,8 +1350,10 @@ bool ARMFastISel::ARMEmitCmp(const Value
if (!SrcEVT.isSimple()) return false;
MVT SrcVT = SrcEVT.getSimpleVT();
- bool isFloat = (Ty->isFloatTy() || Ty->isDoubleTy());
- if (isFloat && !Subtarget->hasVFP2())
+ if (Ty->isFloatTy() && !Subtarget->hasVFP2())
+ return false;
+
+ if (Ty->isDoubleTy() && (!Subtarget->hasVFP2() || Subtarget->isFPOnlySP()))
return false;
// Check to see if the 2nd operand is a constant that we can encode directly
@@ -1501,7 +1503,7 @@ bool ARMFastISel::SelectCmp(const Instru
bool ARMFastISel::SelectFPExt(const Instruction *I) {
// Make sure we have VFP and that we're extending float to double.
- if (!Subtarget->hasVFP2()) return false;
+ if (!Subtarget->hasVFP2() || Subtarget->isFPOnlySP()) return false;
Value *V = I->getOperand(0);
if (!I->getType()->isDoubleTy() ||
@@ -1520,7 +1522,7 @@ bool ARMFastISel::SelectFPExt(const Inst
bool ARMFastISel::SelectFPTrunc(const Instruction *I) {
// Make sure we have VFP and that we're truncating double to float.
- if (!Subtarget->hasVFP2()) return false;
+ if (!Subtarget->hasVFP2() || Subtarget->isFPOnlySP()) return false;
Value *V = I->getOperand(0);
if (!(I->getType()->isFloatTy() &&
@@ -1571,7 +1573,8 @@ bool ARMFastISel::SelectIToFP(const Inst
unsigned Opc;
if (Ty->isFloatTy()) Opc = isSigned ? ARM::VSITOS : ARM::VUITOS;
- else if (Ty->isDoubleTy()) Opc = isSigned ? ARM::VSITOD : ARM::VUITOD;
+ else if (Ty->isDoubleTy() && !Subtarget->isFPOnlySP())
+ Opc = isSigned ? ARM::VSITOD : ARM::VUITOD;
else return false;
unsigned ResultReg = createResultReg(TLI.getRegClassFor(DstVT));
@@ -1596,7 +1599,8 @@ bool ARMFastISel::SelectFPToI(const Inst
unsigned Opc;
Type *OpTy = I->getOperand(0)->getType();
if (OpTy->isFloatTy()) Opc = isSigned ? ARM::VTOSIZS : ARM::VTOUIZS;
- else if (OpTy->isDoubleTy()) Opc = isSigned ? ARM::VTOSIZD : ARM::VTOUIZD;
+ else if (OpTy->isDoubleTy() && !Subtarget->isFPOnlySP())
+ Opc = isSigned ? ARM::VTOSIZD : ARM::VTOUIZD;
else return false;
// f64->s32/u32 or f32->s32/u32 both need an intermediate f32 reg.
@@ -1800,8 +1804,9 @@ bool ARMFastISel::SelectBinaryFPOp(const
// if we have them.
// FIXME: It'd be nice to use NEON instructions.
Type *Ty = I->getType();
- bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
- if (isFloat && !Subtarget->hasVFP2())
+ if (Ty->isFloatTy() && !Subtarget->hasVFP2())
+ return false;
+ if (Ty->isDoubleTy() && (!Subtarget->hasVFP2() || Subtarget->isFPOnlySP()))
return false;
unsigned Opc;
Added: llvm/trunk/test/CodeGen/ARM/fp-only-sp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fp-only-sp.ll?rev=296031&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/fp-only-sp.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/fp-only-sp.ll Thu Feb 23 16:35:00 2017
@@ -0,0 +1,62 @@
+; RUN: llc -mtriple=thumbv7em-apple-macho -mcpu=cortex-m4 %s -o - -O0 | FileCheck %s
+; RUN: llc -mtriple=thumbv7em-apple-macho -mcpu=cortex-m4 %s -o - | FileCheck %s
+
+; Note: vldr and vstr really do have 64-bit variants even with fp-only-sp
+define void @test_load_store(double* %addr) {
+; CHECK-LABEL: test_load_store:
+; CHECK: vldr [[TMP:d[0-9]+]], [r0]
+; CHECK: vstr [[TMP]], [r0]
+ %val = load volatile double, double* %addr
+ store volatile double %val, double* %addr
+ ret void
+}
+
+define void @test_cmp(double %l, double %r, i1* %addr.dst) {
+; CHECK-LABEL: test_cmp:
+; CHECK: bl ___eqdf2
+ %res = fcmp oeq double %l, %r
+ store i1 %res, i1* %addr.dst
+ ret void
+}
+
+define void @test_ext(float %in, double* %addr) {
+; CHECK-LABEL: test_ext:
+; CHECK: bl ___extendsfdf2
+ %res = fpext float %in to double
+ store double %res, double* %addr
+ ret void
+}
+
+define void @test_trunc(double %in, float* %addr) {
+; CHECK-LABEL: test_trunc:
+; CHECK: bl ___truncdfsf2
+ %res = fptrunc double %in to float
+ store float %res, float* %addr
+ ret void
+}
+
+define void @test_itofp(i32 %in, double* %addr) {
+; CHECK-LABEL: test_itofp:
+; CHECK: bl ___floatsidf
+ %res = sitofp i32 %in to double
+ store double %res, double* %addr
+; %res = fptoui double %tmp to i32
+ ret void
+}
+
+define i32 @test_fptoi(double* %addr) {
+; CHECK-LABEL: test_fptoi:
+; CHECK: bl ___fixunsdfsi
+ %val = load double, double* %addr
+ %res = fptoui double %val to i32
+ ret i32 %res
+}
+
+define void @test_binop(double* %addr) {
+; CHECK-LABEL: test_binop:
+; CHECK: bl ___adddf3
+ %in = load double, double* %addr
+ %res = fadd double %in, %in
+ store double %res, double* %addr
+ ret void
+}
More information about the llvm-commits
mailing list