summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64ISelLowering.cpp')
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp44
1 files changed, 20 insertions, 24 deletions
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;
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud