diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2019-02-01 12:26:06 +0000 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2019-02-01 12:26:06 +0000 |
commit | b3ccc5550d985395a7b43cfdd93bc400b332dcdb (patch) | |
tree | acd37f4ea2157bbd8077e13f0627c2b6b3414e9a /llvm/lib/Target | |
parent | f4b19c00b499e26859d0740dec8aecba34e85cbf (diff) | |
download | bcm5719-llvm-b3ccc5550d985395a7b43cfdd93bc400b332dcdb.tar.gz bcm5719-llvm-b3ccc5550d985395a7b43cfdd93bc400b332dcdb.zip |
[AArch64] Optimize floating point materialization
This patch changes isFPImmLegal to return if the value can be enconded
as the immediate operand of a logical instruction besides checking if
for immediate field for fmov.
This optimizes some floating point materization, inclusive values
used on isinf lowering.
Reviewed By: rengolin, efriedma, evandro
Differential Revision: https://reviews.llvm.org/D57044
llvm-svn: 352866
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64FastISel.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 44 |
2 files changed, 23 insertions, 28 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index a63ef542954..8b033ee6376 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -405,10 +405,9 @@ unsigned AArch64FastISel::materializeFP(const ConstantFP *CFP, MVT VT) { bool Is64Bit = (VT == MVT::f64); // This checks to see if we can use FMOV instructions to materialize // a constant, otherwise we have to materialize via the constant pool. - if (TLI.isFPImmLegal(Val, VT)) { - int Imm = - Is64Bit ? AArch64_AM::getFP64Imm(Val) : AArch64_AM::getFP32Imm(Val); - assert((Imm != -1) && "Cannot encode floating-point constant."); + int Imm = + Is64Bit ? AArch64_AM::getFP64Imm(Val) : AArch64_AM::getFP32Imm(Val); + if (Imm != -1) { unsigned Opc = Is64Bit ? AArch64::FMOVDi : AArch64::FMOVSi; return fastEmitInst_i(Opc, TLI.getRegClassFor(VT), Imm); } diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 03a3dacb76f..7198cdcac64 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -5424,34 +5424,30 @@ bool AArch64TargetLowering::isOffsetFoldingLegal( } bool AArch64TargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { - // We can materialize #0.0 as fmov $Rd, XZR for 64-bit and 32-bit cases. - // FIXME: We should be able to handle f128 as well with a clever lowering. - if (Imm.isPosZero() && (VT == MVT::f64 || VT == MVT::f32 || - (VT == MVT::f16 && Subtarget->hasFullFP16()))) { - LLVM_DEBUG(dbgs() << "Legal " << VT.getEVTString() << " imm value: 0\n"); - return true; - } - bool IsLegal = false; - SmallString<128> ImmStrVal; - Imm.toString(ImmStrVal); - + // We can materialize #0.0 as fmov $Rd, XZR for 64-bit, 32-bit cases, and + // 16-bit case when target has full fp16 support. + // FIXME: We should be able to handle f128 as well with a clever lowering. + const APInt ImmInt = Imm.bitcastToAPInt(); if (VT == MVT::f64) - IsLegal = AArch64_AM::getFP64Imm(Imm) != -1; + IsLegal = AArch64_AM::getFP64Imm(ImmInt) != -1 || Imm.isPosZero(); else if (VT == MVT::f32) - IsLegal = AArch64_AM::getFP32Imm(Imm) != -1; + IsLegal = AArch64_AM::getFP32Imm(ImmInt) != -1 || Imm.isPosZero(); else if (VT == MVT::f16 && Subtarget->hasFullFP16()) - IsLegal = AArch64_AM::getFP16Imm(Imm) != -1; - - if (IsLegal) { - LLVM_DEBUG(dbgs() << "Legal " << VT.getEVTString() - << " imm value: " << ImmStrVal << "\n"); - return true; - } - - LLVM_DEBUG(dbgs() << "Illegal " << VT.getEVTString() - << " imm value: " << ImmStrVal << "\n"); - return false; + IsLegal = AArch64_AM::getFP16Imm(ImmInt) != -1 || Imm.isPosZero(); + // TODO: fmov h0, w0 is also legal, however on't have an isel pattern to + // generate that fmov. + + // If we can not materialize in immediate field for fmov, check if the + // value can be encoded as the immediate operand of a logical instruction. + // The immediate value will be created with either MOVZ, MOVN, or ORR. + if (!IsLegal && (VT == MVT::f64 || VT == MVT::f32)) + IsLegal = AArch64_AM::isAnyMOVWMovAlias(ImmInt.getZExtValue(), + VT.getSizeInBits()); + + LLVM_DEBUG(dbgs() << (IsLegal ? "Legal " : "Illegal ") << VT.getEVTString() + << " imm value: "; Imm.dump();); + return IsLegal; } //===----------------------------------------------------------------------===// |