/// exp10(x) for pow(10.0, x); exp2(log2(n) * x) for pow(n, x).
Value *LibCallSimplifier::replacePowWithExp(CallInst *Pow, IRBuilderBase &B) {
Value *Base = Pow->getArgOperand(0), *Expo = Pow->getArgOperand(1);
- AttributeList Attrs = Pow->getCalledFunction()->getAttributes();
+ AttributeList Attrs; // Attributes are only meaningful on the original call
Module *Mod = Pow->getModule();
Type *Ty = Pow->getType();
bool Ignored;
/// Use square root in place of pow(x, +/-0.5).
Value *LibCallSimplifier::replacePowWithSqrt(CallInst *Pow, IRBuilderBase &B) {
Value *Sqrt, *Base = Pow->getArgOperand(0), *Expo = Pow->getArgOperand(1);
- AttributeList Attrs = Pow->getCalledFunction()->getAttributes();
+ AttributeList Attrs; // Attributes are only meaningful on the original call
Module *Mod = Pow->getModule();
Type *Ty = Pow->getType();
Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) {
Function *Callee = CI->getCalledFunction();
+ AttributeList Attrs; // Attributes are only meaningful on the original call
StringRef Name = Callee->getName();
Value *Ret = nullptr;
if (UnsafeFPShrink && Name == TLI->getName(LibFunc_exp2) &&
if (Value *Exp = getIntToFPVal(Op, B))
return emitBinaryFloatFnCall(ConstantFP::get(Ty, 1.0), Exp, TLI,
LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl,
- B, CI->getCalledFunction()->getAttributes());
+ B, Attrs);
}
return Ret;
Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) {
Function *LogFn = Log->getCalledFunction();
- AttributeList Attrs = LogFn->getAttributes();
+ AttributeList Attrs; // Attributes are only meaningful on the original call
StringRef LogNm = LogFn->getName();
Intrinsic::ID LogID = LogFn->getIntrinsicID();
Module *Mod = Log->getModule();
define double @pow_sitofp_double_const_base_2_fast(i32 %x) {
; CHECK-LABEL: @pow_sitofp_double_const_base_2_fast(
-; CHECK-NEXT: [[LDEXPF:%.*]] = call afn float @ldexpf(float 1.000000e+00, i32 [[X:%.*]]) #1
+; CHECK-NEXT: [[LDEXPF:%.*]] = call afn float @ldexpf(float 1.000000e+00, i32 [[X:%.*]])
; CHECK-NEXT: [[RES:%.*]] = fpext float [[LDEXPF]] to double
; CHECK-NEXT: ret double [[RES]]
;
define double @pow_uitofp_const_base_2_fast(i31 %x) {
; CHECK-LABEL: @pow_uitofp_const_base_2_fast(
; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X:%.*]] to i32
-; CHECK-NEXT: [[LDEXPF:%.*]] = call afn float @ldexpf(float 1.000000e+00, i32 [[TMP1]]) #1
+; CHECK-NEXT: [[LDEXPF:%.*]] = call afn float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
; CHECK-NEXT: [[RES:%.*]] = fpext float [[LDEXPF]] to double
; CHECK-NEXT: ret double [[RES]]
;
define double @pow_sitofp_const_base_2_no_fast(i32 %x) {
; CHECK-LABEL: @pow_sitofp_const_base_2_no_fast(
-; CHECK-NEXT: [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[X:%.*]]) #1
+; CHECK-NEXT: [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[X:%.*]])
; CHECK-NEXT: [[RES:%.*]] = fpext float [[LDEXPF]] to double
; CHECK-NEXT: ret double [[RES]]
;
ret i32 %y
}
+declare double @pow(double, double)
+declare double @exp2(double)
+
+; check to make sure only the correct libcall attributes are used
+define double @fake_exp2(double %x) {
+; CHECK-LABEL: @fake_exp2(
+; CHECK-NEXT: [[Y:%.*]] = call double @exp2(double %x)
+; CHECK-NEXT: ret double [[Y]]
+
+ %y = call inreg double @pow(double inreg 2.0, double inreg %x)
+ ret double %y
+}
+define double @fake_ldexp(i32 %x) {
+; CHECK-LABEL: @fake_ldexp(
+; CHECK-NEXT: [[Z:%.*]] = call double @ldexp(double 1.0{{.*}}, i32 %x)
+; CHECK-NEXT: ret double [[Z]]
+
+ %y = sitofp i32 %x to double
+ %z = call inreg double @exp2(double %y)
+ ret double %z
+}
+
attributes #0 = { nobuiltin }
attributes #1 = { builtin }