diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-07-23 05:32:17 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-07-23 05:32:17 +0000 |
| commit | 7d55541e564e800abb14746ec2b1d39c87f6a450 (patch) | |
| tree | f2f9c064aeaf07ba23401e39e79dce9f19a4d6d9 /llvm/lib/Transforms | |
| parent | 7c02cf609d65e9fad58844373d524ff779aa2ded (diff) | |
| download | bcm5719-llvm-7d55541e564e800abb14746ec2b1d39c87f6a450.tar.gz bcm5719-llvm-7d55541e564e800abb14746ec2b1d39c87f6a450.zip | |
Make some existing optimizations that would only trigger on scalars
also apply to vectors. This allows us to compile this:
#include <emmintrin.h>
__m128i a(__m128 a, __m128 b) { return a==a & b==b; }
__m128i b(__m128 a, __m128 b) { return a!=a | b!=b; }
to:
_a:
cmpordps %xmm1, %xmm0
ret
_b:
cmpunordps %xmm1, %xmm0
ret
with clang instead of to a ton of horrible code.
llvm-svn: 76863
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index c3055ae482d..000243ae64f 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -3948,6 +3948,13 @@ Instruction *InstCombiner::FoldAndOfFCmps(Instruction &I, FCmpInst *LHS, return new FCmpInst(*Context, FCmpInst::FCMP_ORD, LHS->getOperand(0), RHS->getOperand(0)); } + + // Handle vector zeros. This occurs because the canonical form of + // "fcmp ord x,x" is "fcmp ord x, 0". + if (isa<ConstantAggregateZero>(LHS->getOperand(1)) && + isa<ConstantAggregateZero>(RHS->getOperand(1))) + return new FCmpInst(*Context, FCmpInst::FCMP_ORD, + LHS->getOperand(0), RHS->getOperand(0)); return 0; } @@ -4242,7 +4249,8 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (CastInst *Op1C = dyn_cast<CastInst>(Op1)) if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind ? const Type *SrcTy = Op0C->getOperand(0)->getType(); - if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isInteger() && + if (SrcTy == Op1C->getOperand(0)->getType() && + SrcTy->isIntOrIntVector() && // Only do this if the casts both really cause code to be generated. ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0), I.getType(), TD) && @@ -4901,7 +4909,8 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { if (!isa<ICmpInst>(Op0C->getOperand(0)) || !isa<ICmpInst>(Op1C->getOperand(0))) { const Type *SrcTy = Op0C->getOperand(0)->getType(); - if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isInteger() && + if (SrcTy == Op1C->getOperand(0)->getType() && + SrcTy->isIntOrIntVector() && // Only do this if the casts both really cause code to be // generated. ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0), @@ -4937,6 +4946,15 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { return new FCmpInst(*Context, FCmpInst::FCMP_UNO, LHS->getOperand(0), RHS->getOperand(0)); } + + // Handle vector zeros. This occurs because the canonical form of + // "fcmp uno x,x" is "fcmp uno x, 0". + if (isa<ConstantAggregateZero>(LHS->getOperand(1)) && + isa<ConstantAggregateZero>(RHS->getOperand(1))) + return new FCmpInst(*Context, FCmpInst::FCMP_UNO, + LHS->getOperand(0), RHS->getOperand(0)); + + } else { Value *Op0LHS, *Op0RHS, *Op1LHS, *Op1RHS; FCmpInst::Predicate Op0CC, Op1CC; |

