Fix a codegen fault in which log2 or exp2 could be dead-code eliminated even though they could have sideeffects.

Only allow log2/exp2 to be converted to an intrinsic if they are declared "readnone".

llvm-svn: 151807
This commit is contained in:
James Molloy 2012-03-01 14:32:18 +00:00
parent 44c3c88cb7
commit 1038b57cac
3 changed files with 34 additions and 2 deletions

View File

@ -5627,7 +5627,8 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
(LibInfo->has(LibFunc::log2l) && Name == "log2l")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType()) {
I.getType() == I.getArgOperand(0)->getType() &&
I.onlyReadsMemory()) {
SDValue Tmp = getValue(I.getArgOperand(0));
setValue(&I, DAG.getNode(ISD::FLOG2, getCurDebugLoc(),
Tmp.getValueType(), Tmp));
@ -5638,7 +5639,8 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
(LibInfo->has(LibFunc::exp2l) && Name == "exp2l")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType()) {
I.getType() == I.getArgOperand(0)->getType() &&
I.onlyReadsMemory()) {
SDValue Tmp = getValue(I.getArgOperand(0));
setValue(&I, DAG.getNode(ISD::FEXP2, getCurDebugLoc(),
Tmp.getValueType(), Tmp));

View File

@ -0,0 +1,15 @@
; RUN: llc -march arm %s -o - | FileCheck %s
; Log2 and exp2 are string-matched to intrinsics. If they are not declared
; readnone, they can't be changed to intrinsics (because they can change errno).
declare double @log2(double)
declare double @exp2(double)
define void @f() {
; CHECK: bl log2
%1 = call double @log2(double 0.000000e+00)
; CHECK: bl exp2
%2 = call double @exp2(double 0.000000e+00)
ret void
}

View File

@ -0,0 +1,15 @@
; RUN: llc -march x86 %s -o - | FileCheck %s
; Log2 and exp2 are string-matched to intrinsics. If they are not declared
; readnone, they can't be changed to intrinsics (because they can change errno).
declare double @log2(double)
declare double @exp2(double)
define void @f() {
; CHECK: calll log2
%1 = call double @log2(double 0.000000e+00)
; CHECK: calll exp2
%2 = call double @exp2(double 0.000000e+00)
ret void
}