summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2015-10-08 17:09:31 +0000
committerSanjay Patel <spatel@rotateright.com>2015-10-08 17:09:31 +0000
commitf61a08fbf106139b6bea1a6e532d8c43e9e67b56 (patch)
tree86be8c99a3f464263738e92ba1345c14e9726095 /llvm/lib/Transforms
parent9115cf8c9dc23e3a9bd0e915f426b4fc694cd133 (diff)
downloadbcm5719-llvm-f61a08fbf106139b6bea1a6e532d8c43e9e67b56.tar.gz
bcm5719-llvm-f61a08fbf106139b6bea1a6e532d8c43e9e67b56.zip
[InstCombine] transform masking off of an FP sign bit into a fabs() intrinsic call (PR24886)
This is a partial fix for PR24886: https://llvm.org/bugs/show_bug.cgi?id=24886 Without this IR transform, the backend (x86 at least) was producing inefficient code. This patch is making 2 assumptions: 1. The canonical form of a fabs() operation is, in fact, the LLVM fabs() intrinsic. 2. The high bit of an FP value is always the sign bit; as noted in the bug report, this isn't specified by the LangRef. Differential Revision: http://reviews.llvm.org/D13076 llvm-svn: 249702
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index d6e87b61177..f72089e6c8e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1488,14 +1488,15 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
return ReplaceInstUsesWith(I, Res);
- // fold (and (cast A), (cast B)) -> (cast (and A, B))
- if (CastInst *Op0C = dyn_cast<CastInst>(Op0))
+ if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
+ Value *Op0COp = Op0C->getOperand(0);
+ Type *SrcTy = Op0COp->getType();
+ // fold (and (cast A), (cast B)) -> (cast (and A, B))
if (CastInst *Op1C = dyn_cast<CastInst>(Op1)) {
- Type *SrcTy = Op0C->getOperand(0)->getType();
if (Op0C->getOpcode() == Op1C->getOpcode() && // same cast kind ?
SrcTy == Op1C->getOperand(0)->getType() &&
SrcTy->isIntOrIntVectorTy()) {
- Value *Op0COp = Op0C->getOperand(0), *Op1COp = Op1C->getOperand(0);
+ Value *Op1COp = Op1C->getOperand(0);
// Only do this if the casts both really cause code to be generated.
if (ShouldOptimizeCast(Op0C->getOpcode(), Op0COp, I.getType()) &&
@@ -1520,6 +1521,20 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
}
}
+ // If we are masking off the sign bit of a floating-point value, convert
+ // this to the canonical fabs intrinsic call and cast back to integer.
+ // The backend should know how to optimize fabs().
+ // TODO: This transform should also apply to vectors.
+ ConstantInt *CI;
+ if (isa<BitCastInst>(Op0C) && SrcTy->isFloatingPointTy() &&
+ match(Op1, m_ConstantInt(CI)) && CI->isMaxValue(true)) {
+ Module *M = I.getParent()->getParent()->getParent();
+ Function *Fabs = Intrinsic::getDeclaration(M, Intrinsic::fabs, SrcTy);
+ Value *Call = Builder->CreateCall(Fabs, Op0COp, "fabs");
+ return CastInst::CreateBitOrPointerCast(Call, I.getType());
+ }
+ }
+
{
Value *X = nullptr;
bool OpsSwapped = false;
OpenPOWER on IntegriCloud