forked from OSchip/llvm-project
[LegalizeTypes] Avoid promotion of exponent in FPOWI
The FPOWI DAG node is normally lowered to a libcall to one of the RTLIB::POWI* runtime functions and the exponent should normally have a type matching sizeof(int) when making the call. Thus, type promotion of the exponent could lead to an FPOWI with a type for the second operand that would be incorrect when doing the libcall (a situation which would be hard to detect post-legalization if we allow such FPOWI nodes). This patch is changing DAGTypeLegalizer::PromoteIntOp_FPOWI to do the rewrite into a libcall directly instead of promoting the operand. This way we can check that the exponent is smaller than sizeof(int) and we can let TargetLowering handle promotion as part of making the libcall. It could be noticed here that makeLibCall has some knowledge about targets such as 64-bit RISCV, for which the libcall argument should be extended to a type larger than sizeof(int). Differential Revision: https://reviews.llvm.org/D102950
This commit is contained in:
parent
9c54ee4378
commit
d1273d39d3
|
@ -18,6 +18,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "LegalizeTypes.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/KnownBits.h"
|
||||
|
@ -1986,8 +1987,44 @@ SDValue DAGTypeLegalizer::PromoteIntOp_PREFETCH(SDNode *N, unsigned OpNo) {
|
|||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntOp_FPOWI(SDNode *N) {
|
||||
SDValue Op = SExtPromotedInteger(N->getOperand(1));
|
||||
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op), 0);
|
||||
// FIXME: Support for promotion of STRICT_FPOWI is not implemented yet.
|
||||
assert(N->getOpcode() == ISD::FPOWI && "No STRICT_FPOWI support here yet.");
|
||||
|
||||
// The integer operand is the last operand in FPOWI (so the result and
|
||||
// floating point operand is already type legalized).
|
||||
|
||||
// We can't just promote the exponent type in FPOWI, since we want to lower
|
||||
// the node to a libcall and we if we promote to a type larger than
|
||||
// sizeof(int) the libcall might not be according to the targets ABI. Instead
|
||||
// we rewrite to a libcall here directly, letting makeLibCall handle promotion
|
||||
// if the target accepts it according to shouldSignExtendTypeInLibCall.
|
||||
RTLIB::Libcall LC;
|
||||
switch (N->getSimpleValueType(0).SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected request for libcall!");
|
||||
case MVT::f32: LC = RTLIB::POWI_F32; break;
|
||||
case MVT::f64: LC = RTLIB::POWI_F64; break;
|
||||
case MVT::f80: LC = RTLIB::POWI_F80; break;
|
||||
case MVT::f128: LC = RTLIB::POWI_F128; break;
|
||||
case MVT::ppcf128: LC = RTLIB::POWI_PPCF128; break;
|
||||
}
|
||||
if (!TLI.getLibcallName(LC)) {
|
||||
// Some targets don't have a powi libcall; use pow instead.
|
||||
// FIXME: Implement this if some target needs it.
|
||||
DAG.getContext()->emitError("Don't know how to promote fpowi to fpow");
|
||||
return DAG.getUNDEF(N->getValueType(0));
|
||||
}
|
||||
// The exponent should fit in a sizeof(int) type for the libcall to be valid.
|
||||
assert(DAG.getLibInfo().getIntSize() ==
|
||||
N->getOperand(1).getValueType().getSizeInBits() &&
|
||||
"POWI exponent should match with sizeof(int) when doing the libcall.");
|
||||
TargetLowering::MakeLibCallOptions CallOptions;
|
||||
CallOptions.setSExt(true);
|
||||
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
|
||||
std::pair<SDValue, SDValue> Tmp =
|
||||
TLI.makeLibCall(DAG, LC, N->getValueType(0), Ops,
|
||||
CallOptions, SDLoc(N), SDValue());
|
||||
ReplaceValueWith(SDValue(N, 0), Tmp.first);
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntOp_VECREDUCE(SDNode *N) {
|
||||
|
|
Loading…
Reference in New Issue