summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/SystemZ
diff options
context:
space:
mode:
authorStephen Lin <stephenwlin@gmail.com>2013-07-09 18:16:56 +0000
committerStephen Lin <stephenwlin@gmail.com>2013-07-09 18:16:56 +0000
commit73de7bf5dec63e8ca45a446373ab61a2e22d103c (patch)
tree61dd22e9276131538d96c046212d55199febb05b /llvm/lib/Target/SystemZ
parentff666bd962a4446d80955fe75619201c29795501 (diff)
downloadbcm5719-llvm-73de7bf5dec63e8ca45a446373ab61a2e22d103c.tar.gz
bcm5719-llvm-73de7bf5dec63e8ca45a446373ab61a2e22d103c.zip
AArch64/PowerPC/SystemZ/X86: This patch fixes the interface, usage, and all
in-tree implementations of TargetLoweringBase::isFMAFasterThanMulAndAdd in order to resolve the following issues with fmuladd (i.e. optional FMA) intrinsics: 1. On X86(-64) targets, ISD::FMA nodes are formed when lowering fmuladd intrinsics even if the subtarget does not support FMA instructions, leading to laughably bad code generation in some situations. 2. On AArch64 targets, ISD::FMA nodes are formed for operations on fp128, resulting in a call to a software fp128 FMA implementation. 3. On PowerPC targets, FMAs are not generated from fmuladd intrinsics on types like v2f32, v8f32, v4f64, etc., even though they promote, split, scalarize, etc. to types that support hardware FMAs. The function has also been slightly renamed for consistency and to force a merge/build conflict for any out-of-tree target implementing it. To resolve, see comments and fixed in-tree examples. llvm-svn: 185956
Diffstat (limited to 'llvm/lib/Target/SystemZ')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelLowering.cpp20
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelLowering.h4
2 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index b1abc2c3c10..d344134b24f 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -255,6 +255,26 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm)
MaxStoresPerMemsetOptSize = 0;
}
+bool
+SystemZTargetLowering::isFMAFasterThanFMulAndFAdd(EVT VT) const {
+ VT = VT.getScalarType();
+
+ if (!VT.isSimple())
+ return false;
+
+ switch (VT.getSimpleVT().SimpleTy) {
+ case MVT::f32:
+ case MVT::f64:
+ return true;
+ case MVT::f128:
+ return false;
+ default:
+ break;
+ }
+
+ return false;
+}
+
bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
// We can load zero using LZ?R and negative zero using LZ?R;LC?BR.
return Imm.isZero() || Imm.isNegZero();
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index 4ddfcbbda05..88e1fa7d746 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -129,9 +129,7 @@ public:
virtual EVT getSetCCResultType(LLVMContext &, EVT) const {
return MVT::i32;
}
- virtual bool isFMAFasterThanMulAndAdd(EVT) const LLVM_OVERRIDE {
- return true;
- }
+ virtual bool isFMAFasterThanFMulAndFAdd(EVT VT) const LLVM_OVERRIDE;
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
virtual bool allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const;
virtual const char *getTargetNodeName(unsigned Opcode) const LLVM_OVERRIDE;
OpenPOWER on IntegriCloud