llvm.org GIT mirror llvm / 53624a2
Refactor and check "onlyReadsMemory" before optimizing builtins. This patch is mostly just refactoring a bunch of copy-and-pasted code, but it also adds a check that the call instructions are readnone or readonly. That check was already present for sin, cos, sqrt, log2, and exp2 calls, but it was missing for the rest of the builtins being handled in this code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161282 91177308-0d34-0410-b5e6-96231b3b80d8 Bob Wilson 7 years ago
13 changed file(s) with 49 addition(s) and 102 deletion(s). Raw diff Collapse all Expand all
55105510 return false;
55115511 }
55125512
5513 /// visitUnaryFloatCall - If a call instruction is a unary floating-point
5514 /// operation (as expected), translate it to an SDNode with the specified opcode
5515 /// and return true.
5516 bool SelectionDAGBuilder::visitUnaryFloatCall(const CallInst &I,
5517 unsigned Opcode) {
5518 // Sanity check that it really is a unary floating-point call.
5519 if (I.getNumArgOperands() != 1 ||
5520 !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
5521 I.getType() != I.getArgOperand(0)->getType() ||
5522 !I.onlyReadsMemory())
5523 return false;
5524
5525 SDValue Tmp = getValue(I.getArgOperand(0));
5526 setValue(&I, DAG.getNode(Opcode, getCurDebugLoc(), Tmp.getValueType(), Tmp));
5527 return true;
5528 }
55135529
55145530 void SelectionDAGBuilder::visitCall(const CallInst &I) {
55155531 // Handle inline assembly differently.
55525568 if (I.getNumArgOperands() == 2 && // Basic sanity checks.
55535569 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
55545570 I.getType() == I.getArgOperand(0)->getType() &&
5555 I.getType() == I.getArgOperand(1)->getType()) {
5571 I.getType() == I.getArgOperand(1)->getType() &&
5572 I.onlyReadsMemory()) {
55565573 SDValue LHS = getValue(I.getArgOperand(0));
55575574 SDValue RHS = getValue(I.getArgOperand(1));
55585575 setValue(&I, DAG.getNode(ISD::FCOPYSIGN, getCurDebugLoc(),
55635580 case LibFunc::fabs:
55645581 case LibFunc::fabsf:
55655582 case LibFunc::fabsl:
5566 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5567 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5568 I.getType() == I.getArgOperand(0)->getType()) {
5569 SDValue Tmp = getValue(I.getArgOperand(0));
5570 setValue(&I, DAG.getNode(ISD::FABS, getCurDebugLoc(),
5571 Tmp.getValueType(), Tmp));
5583 if (visitUnaryFloatCall(I, ISD::FABS))
55725584 return;
5573 }
55745585 break;
55755586 case LibFunc::sin:
55765587 case LibFunc::sinf:
55775588 case LibFunc::sinl:
5578 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5579 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5580 I.getType() == I.getArgOperand(0)->getType() &&
5581 I.onlyReadsMemory()) {
5582 SDValue Tmp = getValue(I.getArgOperand(0));
5583 setValue(&I, DAG.getNode(ISD::FSIN, getCurDebugLoc(),
5584 Tmp.getValueType(), Tmp));
5589 if (visitUnaryFloatCall(I, ISD::FSIN))
55855590 return;
5586 }
55875591 break;
55885592 case LibFunc::cos:
55895593 case LibFunc::cosf:
55905594 case LibFunc::cosl:
5591 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5592 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5593 I.getType() == I.getArgOperand(0)->getType() &&
5594 I.onlyReadsMemory()) {
5595 SDValue Tmp = getValue(I.getArgOperand(0));
5596 setValue(&I, DAG.getNode(ISD::FCOS, getCurDebugLoc(),
5597 Tmp.getValueType(), Tmp));
5595 if (visitUnaryFloatCall(I, ISD::FCOS))
55985596 return;
5599 }
56005597 break;
56015598 case LibFunc::sqrt:
56025599 case LibFunc::sqrtf:
56035600 case LibFunc::sqrtl:
5604 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5605 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5606 I.getType() == I.getArgOperand(0)->getType() &&
5607 I.onlyReadsMemory()) {
5608 SDValue Tmp = getValue(I.getArgOperand(0));
5609 setValue(&I, DAG.getNode(ISD::FSQRT, getCurDebugLoc(),
5610 Tmp.getValueType(), Tmp));
5601 if (visitUnaryFloatCall(I, ISD::FSQRT))
56115602 return;
5612 }
56135603 break;
56145604 case LibFunc::floor:
56155605 case LibFunc::floorf:
56165606 case LibFunc::floorl:
5617 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5618 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5619 I.getType() == I.getArgOperand(0)->getType()) {
5620 SDValue Tmp = getValue(I.getArgOperand(0));
5621 setValue(&I, DAG.getNode(ISD::FFLOOR, getCurDebugLoc(),
5622 Tmp.getValueType(), Tmp));
5607 if (visitUnaryFloatCall(I, ISD::FFLOOR))
56235608 return;
5624 }
56255609 break;
56265610 case LibFunc::nearbyint:
56275611 case LibFunc::nearbyintf:
56285612 case LibFunc::nearbyintl:
5629 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5630 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5631 I.getType() == I.getArgOperand(0)->getType()) {
5632 SDValue Tmp = getValue(I.getArgOperand(0));
5633 setValue(&I, DAG.getNode(ISD::FNEARBYINT, getCurDebugLoc(),
5634 Tmp.getValueType(), Tmp));
5613 if (visitUnaryFloatCall(I, ISD::FNEARBYINT))
56355614 return;
5636 }
56375615 break;
56385616 case LibFunc::ceil:
56395617 case LibFunc::ceilf:
56405618 case LibFunc::ceill:
5641 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5642 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5643 I.getType() == I.getArgOperand(0)->getType()) {
5644 SDValue Tmp = getValue(I.getArgOperand(0));
5645 setValue(&I, DAG.getNode(ISD::FCEIL, getCurDebugLoc(),
5646 Tmp.getValueType(), Tmp));
5619 if (visitUnaryFloatCall(I, ISD::FCEIL))
56475620 return;
5648 }
56495621 break;
56505622 case LibFunc::rint:
56515623 case LibFunc::rintf:
56525624 case LibFunc::rintl:
5653 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5654 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5655 I.getType() == I.getArgOperand(0)->getType()) {
5656 SDValue Tmp = getValue(I.getArgOperand(0));
5657 setValue(&I, DAG.getNode(ISD::FRINT, getCurDebugLoc(),
5658 Tmp.getValueType(), Tmp));
5625 if (visitUnaryFloatCall(I, ISD::FRINT))
56595626 return;
5660 }
56615627 break;
56625628 case LibFunc::trunc:
56635629 case LibFunc::truncf:
56645630 case LibFunc::truncl:
5665 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5666 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5667 I.getType() == I.getArgOperand(0)->getType()) {
5668 SDValue Tmp = getValue(I.getArgOperand(0));
5669 setValue(&I, DAG.getNode(ISD::FTRUNC, getCurDebugLoc(),
5670 Tmp.getValueType(), Tmp));
5631 if (visitUnaryFloatCall(I, ISD::FTRUNC))
56715632 return;
5672 }
56735633 break;
56745634 case LibFunc::log2:
56755635 case LibFunc::log2f:
56765636 case LibFunc::log2l:
5677 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5678 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5679 I.getType() == I.getArgOperand(0)->getType() &&
5680 I.onlyReadsMemory()) {
5681 SDValue Tmp = getValue(I.getArgOperand(0));
5682 setValue(&I, DAG.getNode(ISD::FLOG2, getCurDebugLoc(),
5683 Tmp.getValueType(), Tmp));
5637 if (visitUnaryFloatCall(I, ISD::FLOG2))
56845638 return;
5685 }
56865639 break;
56875640 case LibFunc::exp2:
56885641 case LibFunc::exp2f:
56895642 case LibFunc::exp2l:
5690 if (I.getNumArgOperands() == 1 && // Basic sanity checks.
5691 I.getArgOperand(0)->getType()->isFloatingPointTy() &&
5692 I.getType() == I.getArgOperand(0)->getType() &&
5693 I.onlyReadsMemory()) {
5694 SDValue Tmp = getValue(I.getArgOperand(0));
5695 setValue(&I, DAG.getNode(ISD::FEXP2, getCurDebugLoc(),
5696 Tmp.getValueType(), Tmp));
5643 if (visitUnaryFloatCall(I, ISD::FEXP2))
56975644 return;
5698 }
56995645 break;
57005646 case LibFunc::memcmp:
57015647 if (visitMemCmpCall(I))
519519 void visitPHI(const PHINode &I);
520520 void visitCall(const CallInst &I);
521521 bool visitMemCmpCall(const CallInst &I);
522 bool visitUnaryFloatCall(const CallInst &I, unsigned Opcode);
522523 void visitAtomicLoad(const LoadInst &I);
523524 void visitAtomicStore(const StoreInst &I);
524525
55 define float @test(float %a, float %b) {
66 entry:
77 %dum = fadd float %a, %b
8 %0 = tail call float @fabsf(float %dum)
8 %0 = tail call float @fabsf(float %dum) readnone
99 %dum1 = fadd float %0, %b
1010 ret float %dum1
1111 }
1010 ; HARD: test1:
1111 ; HARD: vmov.i32 [[REG1:(d[0-9]+)]], #0x80000000
1212 ; HARD: vbsl [[REG1]], d
13 %0 = tail call float @copysignf(float %x, float %y) nounwind
13 %0 = tail call float @copysignf(float %x, float %y) nounwind readnone
1414 ret float %0
1515 }
1616
2424 ; HARD: vmov.i32 [[REG2:(d[0-9]+)]], #0x80000000
2525 ; HARD: vshl.i64 [[REG2]], [[REG2]], #32
2626 ; HARD: vbsl [[REG2]], d1, d0
27 %0 = tail call double @copysign(double %x, double %y) nounwind
27 %0 = tail call double @copysign(double %x, double %y) nounwind readnone
2828 ret double %0
2929 }
3030
3535 ; SOFT: vshl.i64 [[REG3]], [[REG3]], #32
3636 ; SOFT: vbsl [[REG3]],
3737 %0 = fmul double %x, %y
38 %1 = tail call double @copysign(double %0, double %z) nounwind
38 %1 = tail call double @copysign(double %0, double %z) nounwind readnone
3939 ret double %1
4040 }
4141
8383 ;CHECK: f11:
8484 ;CHECK: bic
8585 entry:
86 %tmp1 = call float @fabsf( float %a ) ; [#uses=1]
86 %tmp1 = call float @fabsf( float %a ) readnone ; [#uses=1]
8787 ret float %tmp1
8888 }
8989
9393 ;CHECK: f12:
9494 ;CHECK: vabs.f64
9595 entry:
96 %tmp1 = call double @fabs( double %a ) ; [#uses=1]
96 %tmp1 = call double @fabs( double %a ) readnone ; [#uses=1]
9797 ret double %tmp1
9898 }
9999
1616 ;CHECK: test_abs:
1717 %a = load float* %P ; [#uses=1]
1818 ;CHECK: vabs.f32
19 %b = call float @fabsf( float %a ) ; [#uses=1]
19 %b = call float @fabsf( float %a ) readnone ; [#uses=1]
2020 store float %b, float* %P
2121 %A = load double* %D ; [#uses=1]
2222 ;CHECK: vabs.f64
23 %B = call double @fabs( double %A ) ; [#uses=1]
23 %B = call double @fabs( double %A ) readnone ; [#uses=1]
2424 store double %B, double* %D
2525 ret void
2626 }
1414 define i1 @fcmp_mag_eq(float %arg1, float %arg2) {
1515 ; CHECK: fcmeq
1616 ; CHECK: bi $lr
17 %1 = call float @fabsf(float %arg1)
18 %2 = call float @fabsf(float %arg2)
17 %1 = call float @fabsf(float %arg1) readnone
18 %2 = call float @fabsf(float %arg2) readnone
1919 %3 = fcmp oeq float %1, %2
2020 ret i1 %3
2121 }
3131 declare float @fabsf(float)
3232
3333 define double @fabs_dp(double %X) {
34 %Y = call double @fabs( double %X )
34 %Y = call double @fabs( double %X ) readnone
3535 ret double %Y
3636 }
3737
3838 define float @fabs_sp(float %X) {
39 %Y = call float @fabsf( float %X )
39 %Y = call float @fabsf( float %X ) readnone
4040 ret float %Y
4141 }
77 %x.addr = alloca float, align 4
88 store float %x, float* %x.addr, align 4
99 %0 = load float* %x.addr, align 4
10 %call = call float @fabsf(float %0)
10 %call = call float @fabsf(float %0) readnone
1111 ret float %call
1212 }
1313
11
22 define double @fabs(double %f) {
33 entry:
4 %tmp2 = tail call double @fabs( double %f ) ; [#uses=1]
4 %tmp2 = tail call double @fabs( double %f ) readnone ; [#uses=1]
55 ret double %tmp2
66 }
22 declare double @fabs(double)
33
44 define double @test(double %X) {
5 %Y = call double @fabs( double %X ) ; [#uses=1]
5 %Y = call double @fabs( double %X ) readnone ; [#uses=1]
66 %Z = fsub double -0.000000e+00, %Y ; [#uses=1]
77 ret double %Z
88 }
1010 ; UNSAFE: test1:
1111 ; NOOPT: test1:
1212 define float @test1(float %X) {
13 %Y = call float @fabsf(float %X)
13 %Y = call float @fabsf(float %X) readnone
1414 ret float %Y
1515 }
1616 ; CHECK: {{^[ \t]+fabs$}}
4141 ; UNSAFE: test3:
4242 ; NOOPT: test3:
4343 define x86_fp80 @test3(x86_fp80 %X) {
44 %Y = call x86_fp80 @fabsl(x86_fp80 %X)
44 %Y = call x86_fp80 @fabsl(x86_fp80 %X) readnone
4545 ret x86_fp80 %Y
4646 }
4747 ; CHECK: {{^[ \t]+fabs$}}
99 define void @test({ double, double }* byval %z, double* %P) nounwind {
1010 entry:
1111 %tmp3 = load double* @G, align 16 ; [#uses=1]
12 %tmp4 = tail call double @fabs( double %tmp3 ) ; [#uses=1]
12 %tmp4 = tail call double @fabs( double %tmp3 ) readnone ; [#uses=1]
1313 store volatile double %tmp4, double* %P
1414 %tmp = getelementptr { double, double }* %z, i32 0, i32 0 ; [#uses=1]
1515 %tmp1 = load volatile double* %tmp, align 8 ; [#uses=1]
16 %tmp2 = tail call double @fabs( double %tmp1 ) ; [#uses=1]
16 %tmp2 = tail call double @fabs( double %tmp1 ) readnone ; [#uses=1]
1717 ; CHECK: andpd{{.*}}4(%esp), %xmm
1818 %tmp6 = fadd double %tmp4, %tmp2 ; [#uses=1]
1919 store volatile double %tmp6, double* %P, align 8