Add target hook CodeGen queries when generating builtin pow*.
Without fmath-errno, Clang currently generates calls to @llvm.pow.* intrinsics when it sees pow*(). This may not be suitable for all targets (for example le32/PNaCl), so the attached patch adds a target hook that CodeGen queries. The target can state its preference for having or not having the intrinsic generated. Non-PNaCl behavior remains unchanged; PNaCl-specific test added. llvm-svn: 185568
This commit is contained in:
parent
7a433802cf
commit
9b64ec18c1
|
|
@ -1293,13 +1293,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
case Builtin::BIpow:
|
||||
case Builtin::BIpowf:
|
||||
case Builtin::BIpowl: {
|
||||
if (!FD->hasAttr<ConstAttr>())
|
||||
break;
|
||||
Value *Base = EmitScalarExpr(E->getArg(0));
|
||||
Value *Exponent = EmitScalarExpr(E->getArg(1));
|
||||
llvm::Type *ArgType = Base->getType();
|
||||
Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType);
|
||||
return RValue::get(Builder.CreateCall2(F, Base, Exponent));
|
||||
// Transform a call to pow* into a @llvm.pow.* intrinsic call, but only
|
||||
// if the target agrees.
|
||||
if (getTargetHooks().emitIntrinsicForPow()) {
|
||||
if (!FD->hasAttr<ConstAttr>())
|
||||
break;
|
||||
Value *Base = EmitScalarExpr(E->getArg(0));
|
||||
Value *Exponent = EmitScalarExpr(E->getArg(1));
|
||||
llvm::Type *ArgType = Base->getType();
|
||||
Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType);
|
||||
return RValue::get(Builder.CreateCall2(F, Base, Exponent));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Builtin::BIfma:
|
||||
|
|
|
|||
|
|
@ -443,6 +443,10 @@ class PNaClTargetCodeGenInfo : public TargetCodeGenInfo {
|
|||
public:
|
||||
PNaClTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
|
||||
: TargetCodeGenInfo(new PNaClABIInfo(CGT)) {}
|
||||
|
||||
/// For PNaCl we don't want llvm.pow.* intrinsics to be emitted instead
|
||||
/// of library function calls.
|
||||
bool emitIntrinsicForPow() const { return false; }
|
||||
};
|
||||
|
||||
void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,10 @@ namespace clang {
|
|||
/// through such registers.
|
||||
virtual bool extendPointerWithSExt() const { return false; }
|
||||
|
||||
/// Controls whether BIpow* emit an intrinsic call instead of a library
|
||||
/// function call.
|
||||
virtual bool emitIntrinsicForPow() const { return true; }
|
||||
|
||||
/// Determines the DWARF register number for the stack pointer, for
|
||||
/// exception-handling purposes. Implements __builtin_dwarf_sp_column.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: %clang_cc1 -fmath-errno -emit-llvm -o - %s -triple le32-unknown-nacl | FileCheck %s
|
||||
// RUN: %clang_cc1 -emit-llvm -o - %s -triple le32-unknown-nacl | FileCheck %s
|
||||
|
||||
// le32 (PNaCl) never generates intrinsics for pow calls, with or without errno
|
||||
|
||||
// CHECK: define void @test_pow
|
||||
void test_pow(float a0, double a1, long double a2) {
|
||||
// CHECK: call float @powf
|
||||
float l0 = powf(a0, a0);
|
||||
|
||||
// CHECK: call double @pow
|
||||
double l1 = pow(a1, a1);
|
||||
|
||||
// CHECK: call double @powl
|
||||
long double l2 = powl(a2, a2);
|
||||
}
|
||||
|
||||
// CHECK: declare float @powf(float, float)
|
||||
// CHECK: declare double @pow(double, double)
|
||||
// CHECK: declare double @powl(double, double)
|
||||
|
||||
Loading…
Reference in New Issue