2002-08-12 21:17:25 +00:00
|
|
|
//===- InstructionCombining.cpp - Combine multiple instructions -----------===//
|
2003-10-20 19:43:21 +00:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file was developed by the LLVM research group and is distributed under
|
|
|
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2001-12-14 16:52:21 +00:00
|
|
|
//
|
|
|
|
// InstructionCombining - Combine instructions to form fewer, simple
|
2002-09-02 04:59:56 +00:00
|
|
|
// instructions. This pass does not modify the CFG This pass is where algebraic
|
|
|
|
// simplification happens.
|
2001-12-14 16:52:21 +00:00
|
|
|
//
|
|
|
|
// This pass combines things like:
|
2004-05-04 15:19:33 +00:00
|
|
|
// %Y = add int %X, 1
|
|
|
|
// %Z = add int %Y, 1
|
2001-12-14 16:52:21 +00:00
|
|
|
// into:
|
2004-05-04 15:19:33 +00:00
|
|
|
// %Z = add int %X, 2
|
2001-12-14 16:52:21 +00:00
|
|
|
//
|
|
|
|
// This is a simple worklist driven algorithm.
|
|
|
|
//
|
2003-09-10 05:29:43 +00:00
|
|
|
// This pass guarantees that the following canonicalizations are performed on
|
2003-07-23 21:41:57 +00:00
|
|
|
// the program:
|
|
|
|
// 1. If a binary operator has a constant operand, it is moved to the RHS
|
2003-08-12 21:53:41 +00:00
|
|
|
// 2. Bitwise operators with constant operands are always grouped so that
|
|
|
|
// shifts are performed first, then or's, then and's, then xor's.
|
2003-07-23 21:41:57 +00:00
|
|
|
// 3. SetCC instructions are converted from <,>,<=,>= to ==,!= if possible
|
|
|
|
// 4. All SetCC instructions on boolean values are replaced with logical ops
|
2003-08-13 04:18:28 +00:00
|
|
|
// 5. add X, X is represented as (X*2) => (X << 1)
|
|
|
|
// 6. Multiplies with a power-of-two constant argument are transformed into
|
|
|
|
// shifts.
|
2004-11-14 19:13:23 +00:00
|
|
|
// ... etc.
|
2003-07-23 21:41:57 +00:00
|
|
|
//
|
2001-12-14 16:52:21 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2004-03-13 23:54:27 +00:00
|
|
|
#define DEBUG_TYPE "instcombine"
|
2002-05-07 20:03:00 +00:00
|
|
|
#include "llvm/Transforms/Scalar.h"
|
2004-10-12 04:52:52 +00:00
|
|
|
#include "llvm/IntrinsicInst.h"
|
2002-02-26 21:46:54 +00:00
|
|
|
#include "llvm/Pass.h"
|
2002-11-04 16:18:53 +00:00
|
|
|
#include "llvm/DerivedTypes.h"
|
2003-06-26 05:06:25 +00:00
|
|
|
#include "llvm/GlobalVariable.h"
|
2003-11-02 05:57:39 +00:00
|
|
|
#include "llvm/Target/TargetData.h"
|
|
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
|
|
#include "llvm/Transforms/Utils/Local.h"
|
2004-04-05 01:30:19 +00:00
|
|
|
#include "llvm/Support/CallSite.h"
|
|
|
|
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
2002-02-12 21:07:25 +00:00
|
|
|
#include "llvm/Support/InstIterator.h"
|
2002-04-18 17:39:14 +00:00
|
|
|
#include "llvm/Support/InstVisitor.h"
|
2004-07-30 07:50:03 +00:00
|
|
|
#include "llvm/Support/PatternMatch.h"
|
2004-09-01 22:55:40 +00:00
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include "llvm/ADT/Statistic.h"
|
2002-05-14 15:24:07 +00:00
|
|
|
#include <algorithm>
|
2003-12-07 01:24:23 +00:00
|
|
|
using namespace llvm;
|
2004-07-30 07:50:03 +00:00
|
|
|
using namespace llvm::PatternMatch;
|
2003-11-11 22:41:34 +00:00
|
|
|
|
2002-04-18 17:39:14 +00:00
|
|
|
namespace {
|
2002-10-01 22:38:41 +00:00
|
|
|
Statistic<> NumCombined ("instcombine", "Number of insts combined");
|
|
|
|
Statistic<> NumConstProp("instcombine", "Number of constant folds");
|
|
|
|
Statistic<> NumDeadInst ("instcombine", "Number of dead inst eliminated");
|
|
|
|
|
2002-04-27 06:56:12 +00:00
|
|
|
class InstCombiner : public FunctionPass,
|
2002-04-18 17:39:14 +00:00
|
|
|
public InstVisitor<InstCombiner, Instruction*> {
|
|
|
|
// Worklist of all of the instructions that need to be simplified.
|
|
|
|
std::vector<Instruction*> WorkList;
|
2003-11-02 05:57:39 +00:00
|
|
|
TargetData *TD;
|
2002-04-18 17:39:14 +00:00
|
|
|
|
2004-02-28 05:22:00 +00:00
|
|
|
/// AddUsersToWorkList - When an instruction is simplified, add all users of
|
|
|
|
/// the instruction to the work lists because they might get more simplified
|
|
|
|
/// now.
|
|
|
|
///
|
|
|
|
void AddUsersToWorkList(Instruction &I) {
|
2002-06-25 16:13:24 +00:00
|
|
|
for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
|
2002-04-18 17:39:14 +00:00
|
|
|
UI != UE; ++UI)
|
|
|
|
WorkList.push_back(cast<Instruction>(*UI));
|
|
|
|
}
|
|
|
|
|
2004-02-28 05:22:00 +00:00
|
|
|
/// AddUsesToWorkList - When an instruction is simplified, add operands to
|
|
|
|
/// the work lists because they might get more simplified now.
|
|
|
|
///
|
|
|
|
void AddUsesToWorkList(Instruction &I) {
|
|
|
|
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
|
|
|
|
if (Instruction *Op = dyn_cast<Instruction>(I.getOperand(i)))
|
|
|
|
WorkList.push_back(Op);
|
|
|
|
}
|
|
|
|
|
2002-09-02 04:59:56 +00:00
|
|
|
// removeFromWorkList - remove all instances of I from the worklist.
|
|
|
|
void removeFromWorkList(Instruction *I);
|
2002-04-18 17:39:14 +00:00
|
|
|
public:
|
2002-06-25 16:13:24 +00:00
|
|
|
virtual bool runOnFunction(Function &F);
|
2002-04-18 17:39:14 +00:00
|
|
|
|
2002-04-28 21:27:06 +00:00
|
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
2003-11-02 05:57:39 +00:00
|
|
|
AU.addRequired<TargetData>();
|
2002-10-21 20:00:28 +00:00
|
|
|
AU.setPreservesCFG();
|
2002-04-28 21:27:06 +00:00
|
|
|
}
|
|
|
|
|
2004-04-05 01:30:19 +00:00
|
|
|
TargetData &getTargetData() const { return *TD; }
|
|
|
|
|
2002-04-18 17:39:14 +00:00
|
|
|
// Visitation implementation - Implement instruction combining for different
|
|
|
|
// instruction types. The semantics are as follows:
|
|
|
|
// Return Value:
|
|
|
|
// null - No change was made
|
2002-08-12 21:17:25 +00:00
|
|
|
// I - Change was made, I is still valid, I may be dead though
|
2002-04-18 17:39:14 +00:00
|
|
|
// otherwise - Change was made, replace I with returned instruction
|
|
|
|
//
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *visitAdd(BinaryOperator &I);
|
|
|
|
Instruction *visitSub(BinaryOperator &I);
|
|
|
|
Instruction *visitMul(BinaryOperator &I);
|
|
|
|
Instruction *visitDiv(BinaryOperator &I);
|
|
|
|
Instruction *visitRem(BinaryOperator &I);
|
|
|
|
Instruction *visitAnd(BinaryOperator &I);
|
|
|
|
Instruction *visitOr (BinaryOperator &I);
|
|
|
|
Instruction *visitXor(BinaryOperator &I);
|
|
|
|
Instruction *visitSetCondInst(BinaryOperator &I);
|
2004-11-28 21:31:15 +00:00
|
|
|
Instruction *visitSetCondInstWithCastAndConstant(BinaryOperator&I,
|
|
|
|
CastInst*LHSI,
|
|
|
|
ConstantInt* CI);
|
2003-03-10 19:16:08 +00:00
|
|
|
Instruction *visitShiftInst(ShiftInst &I);
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *visitCastInst(CastInst &CI);
|
2004-03-12 05:52:32 +00:00
|
|
|
Instruction *visitSelectInst(SelectInst &CI);
|
2003-06-19 17:00:31 +00:00
|
|
|
Instruction *visitCallInst(CallInst &CI);
|
|
|
|
Instruction *visitInvokeInst(InvokeInst &II);
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *visitPHINode(PHINode &PN);
|
|
|
|
Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP);
|
2002-11-04 16:18:53 +00:00
|
|
|
Instruction *visitAllocationInst(AllocationInst &AI);
|
2003-12-07 01:24:23 +00:00
|
|
|
Instruction *visitFreeInst(FreeInst &FI);
|
2003-06-26 05:06:25 +00:00
|
|
|
Instruction *visitLoadInst(LoadInst &LI);
|
2003-06-04 04:46:00 +00:00
|
|
|
Instruction *visitBranchInst(BranchInst &BI);
|
2004-07-03 00:26:11 +00:00
|
|
|
Instruction *visitSwitchInst(SwitchInst &SI);
|
2002-04-18 17:39:14 +00:00
|
|
|
|
|
|
|
// visitInstruction - Specify what to return for unhandled instructions...
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *visitInstruction(Instruction &I) { return 0; }
|
2002-08-09 23:47:40 +00:00
|
|
|
|
2003-06-19 17:00:31 +00:00
|
|
|
private:
|
2003-10-07 22:32:43 +00:00
|
|
|
Instruction *visitCallSite(CallSite CS);
|
2003-06-19 17:00:31 +00:00
|
|
|
bool transformConstExprCastCall(CallSite CS);
|
|
|
|
|
2004-04-05 01:30:19 +00:00
|
|
|
public:
|
2002-08-09 23:47:40 +00:00
|
|
|
// InsertNewInstBefore - insert an instruction New before instruction Old
|
|
|
|
// in the program. Add the new instruction to the worklist.
|
|
|
|
//
|
Fold (and (setcc X, C1), (setcc X, C2))
This is important for several reasons:
1. Benchmarks have lots of code that looks like this (perlbmk in particular):
%tmp.2.i = setne int %tmp.0.i, 128 ; <bool> [#uses=1]
%tmp.6343 = seteq int %tmp.0.i, 1 ; <bool> [#uses=1]
%tmp.63 = and bool %tmp.2.i, %tmp.6343 ; <bool> [#uses=1]
we now fold away the setne, a clear improvement.
2. In the more important cases, such as (X >= 10) & (X < 20), we now produce
smaller code: (X-10) < 10.
3. Perhaps the nicest effect of this patch is that it really helps out the
code generators. In particular, for a 'range test' like the above,
instead of generating this on X86 (the difference on PPC is even more
pronounced):
cmp %EAX, 50
setge %CL
cmp %EAX, 100
setl %AL
and %CL, %AL
cmp %CL, 0
we now generate this:
add %EAX, -50
cmp %EAX, 50
Furthermore, this causes setcc's to be folded into branches more often.
These combinations trigger dozens of times in the spec benchmarks, particularly
in 176.gcc, 186.crafty, 253.perlbmk, 254.gap, & 099.go.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16559 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-28 21:48:02 +00:00
|
|
|
Instruction *InsertNewInstBefore(Instruction *New, Instruction &Old) {
|
2002-08-23 18:32:43 +00:00
|
|
|
assert(New && New->getParent() == 0 &&
|
|
|
|
"New instruction already inserted into a basic block!");
|
2002-08-09 23:47:40 +00:00
|
|
|
BasicBlock *BB = Old.getParent();
|
|
|
|
BB->getInstList().insert(&Old, New); // Insert inst
|
|
|
|
WorkList.push_back(New); // Add to worklist
|
2004-02-23 06:38:22 +00:00
|
|
|
return New;
|
2002-08-09 23:47:40 +00:00
|
|
|
}
|
|
|
|
|
2004-09-24 15:21:34 +00:00
|
|
|
/// InsertCastBefore - Insert a cast of V to TY before the instruction POS.
|
|
|
|
/// This also adds the cast to the worklist. Finally, this returns the
|
|
|
|
/// cast.
|
|
|
|
Value *InsertCastBefore(Value *V, const Type *Ty, Instruction &Pos) {
|
|
|
|
if (V->getType() == Ty) return V;
|
|
|
|
|
|
|
|
Instruction *C = new CastInst(V, Ty, V->getName(), &Pos);
|
|
|
|
WorkList.push_back(C);
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
2002-08-09 23:47:40 +00:00
|
|
|
// ReplaceInstUsesWith - This method is to be used when an instruction is
|
|
|
|
// found to be dead, replacable with another preexisting expression. Here
|
|
|
|
// we add all uses of I to the worklist, replace all uses of I with the new
|
|
|
|
// value, then return I, so that the inst combiner will know that I was
|
|
|
|
// modified.
|
|
|
|
//
|
|
|
|
Instruction *ReplaceInstUsesWith(Instruction &I, Value *V) {
|
2004-02-28 05:22:00 +00:00
|
|
|
AddUsersToWorkList(I); // Add all modified instrs to worklist
|
2004-04-05 02:10:19 +00:00
|
|
|
if (&I != V) {
|
|
|
|
I.replaceAllUsesWith(V);
|
|
|
|
return &I;
|
|
|
|
} else {
|
|
|
|
// If we are replacing the instruction with itself, this must be in a
|
|
|
|
// segment of unreachable code, so just clobber the instruction.
|
2004-10-18 02:59:09 +00:00
|
|
|
I.replaceAllUsesWith(UndefValue::get(I.getType()));
|
2004-04-05 02:10:19 +00:00
|
|
|
return &I;
|
|
|
|
}
|
2002-08-09 23:47:40 +00:00
|
|
|
}
|
2004-02-28 05:22:00 +00:00
|
|
|
|
|
|
|
// EraseInstFromFunction - When dealing with an instruction that has side
|
|
|
|
// effects or produces a void value, we can't rely on DCE to delete the
|
|
|
|
// instruction. Instead, visit methods should return the value returned by
|
|
|
|
// this function.
|
|
|
|
Instruction *EraseInstFromFunction(Instruction &I) {
|
|
|
|
assert(I.use_empty() && "Cannot erase instruction that is used!");
|
|
|
|
AddUsesToWorkList(I);
|
|
|
|
removeFromWorkList(&I);
|
2004-11-18 21:41:39 +00:00
|
|
|
I.eraseFromParent();
|
2004-02-28 05:22:00 +00:00
|
|
|
return 0; // Don't do anything with FI
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-08-13 20:16:26 +00:00
|
|
|
private:
|
2003-07-24 17:35:25 +00:00
|
|
|
/// InsertOperandCastBefore - This inserts a cast of V to DestTy before the
|
|
|
|
/// InsertBefore instruction. This is specialized a bit to avoid inserting
|
|
|
|
/// casts that are known to not do anything...
|
|
|
|
///
|
|
|
|
Value *InsertOperandCastBefore(Value *V, const Type *DestTy,
|
|
|
|
Instruction *InsertBefore);
|
|
|
|
|
2003-03-11 00:12:48 +00:00
|
|
|
// SimplifyCommutative - This performs a few simplifications for commutative
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
// operators.
|
2003-03-11 00:12:48 +00:00
|
|
|
bool SimplifyCommutative(BinaryOperator &I);
|
2003-09-19 17:17:26 +00:00
|
|
|
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
|
|
|
|
// FoldOpIntoPhi - Given a binary operator or cast instruction which has a
|
|
|
|
// PHI node as operand #0, see if we can fold the instruction into the PHI
|
|
|
|
// (which is only possible if all operands to the PHI are constants).
|
|
|
|
Instruction *FoldOpIntoPhi(Instruction &I);
|
|
|
|
|
2004-11-14 19:13:23 +00:00
|
|
|
// FoldPHIArgOpIntoPHI - If all operands to a PHI node are the same "unary"
|
|
|
|
// operator and they all are only used by the PHI, PHI together their
|
|
|
|
// inputs, and do the operation once, to the result of the PHI.
|
|
|
|
Instruction *FoldPHIArgOpIntoPHI(PHINode &PN);
|
|
|
|
|
2003-09-19 17:17:26 +00:00
|
|
|
Instruction *OptAndOp(Instruction *Op, ConstantIntegral *OpRHS,
|
|
|
|
ConstantIntegral *AndRHS, BinaryOperator &TheAnd);
|
2004-09-29 17:40:11 +00:00
|
|
|
|
|
|
|
Instruction *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
|
|
|
|
bool Inside, Instruction &IB);
|
2002-04-18 17:39:14 +00:00
|
|
|
};
|
2002-07-23 18:06:35 +00:00
|
|
|
|
2002-07-26 21:12:46 +00:00
|
|
|
RegisterOpt<InstCombiner> X("instcombine", "Combine redundant instructions");
|
2002-04-18 17:39:14 +00:00
|
|
|
}
|
|
|
|
|
2003-03-10 21:43:22 +00:00
|
|
|
// getComplexity: Assign a complexity or rank value to LLVM Values...
|
2004-10-16 18:11:37 +00:00
|
|
|
// 0 -> undef, 1 -> Const, 2 -> Other, 3 -> Arg, 3 -> Unary, 4 -> OtherInst
|
2003-03-10 21:43:22 +00:00
|
|
|
static unsigned getComplexity(Value *V) {
|
|
|
|
if (isa<Instruction>(V)) {
|
|
|
|
if (BinaryOperator::isNeg(V) || BinaryOperator::isNot(V))
|
2004-10-16 18:11:37 +00:00
|
|
|
return 3;
|
|
|
|
return 4;
|
2003-03-10 21:43:22 +00:00
|
|
|
}
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<Argument>(V)) return 3;
|
|
|
|
return isa<Constant>(V) ? (isa<UndefValue>(V) ? 0 : 1) : 2;
|
2003-03-10 21:43:22 +00:00
|
|
|
}
|
2002-04-18 17:39:14 +00:00
|
|
|
|
2003-03-11 00:12:48 +00:00
|
|
|
// isOnlyUse - Return true if this instruction will be deleted if we stop using
|
|
|
|
// it.
|
|
|
|
static bool isOnlyUse(Value *V) {
|
2003-10-15 16:48:29 +00:00
|
|
|
return V->hasOneUse() || isa<Constant>(V);
|
2003-03-11 00:12:48 +00:00
|
|
|
}
|
|
|
|
|
2004-02-23 06:38:22 +00:00
|
|
|
// getPromotedType - Return the specified type promoted as it would be to pass
|
|
|
|
// though a va_arg area...
|
|
|
|
static const Type *getPromotedType(const Type *Ty) {
|
2004-06-17 18:16:02 +00:00
|
|
|
switch (Ty->getTypeID()) {
|
2004-02-23 06:38:22 +00:00
|
|
|
case Type::SByteTyID:
|
|
|
|
case Type::ShortTyID: return Type::IntTy;
|
|
|
|
case Type::UByteTyID:
|
|
|
|
case Type::UShortTyID: return Type::UIntTy;
|
|
|
|
case Type::FloatTyID: return Type::DoubleTy;
|
|
|
|
default: return Ty;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-10 21:43:22 +00:00
|
|
|
// SimplifyCommutative - This performs a few simplifications for commutative
|
|
|
|
// operators:
|
|
|
|
//
|
|
|
|
// 1. Order operands such that they are listed from right (least complex) to
|
|
|
|
// left (most complex). This puts constants before unary operators before
|
|
|
|
// binary operators.
|
2002-04-18 17:39:14 +00:00
|
|
|
//
|
2003-03-11 00:12:48 +00:00
|
|
|
// 2. Transform: (op (op V, C1), C2) ==> (op V, (op C1, C2))
|
|
|
|
// 3. Transform: (op (op V1, C1), (op V2, C2)) ==> (op (op V1, V2), (op C1,C2))
|
2003-03-10 21:43:22 +00:00
|
|
|
//
|
2003-03-11 00:12:48 +00:00
|
|
|
bool InstCombiner::SimplifyCommutative(BinaryOperator &I) {
|
2003-03-10 21:43:22 +00:00
|
|
|
bool Changed = false;
|
|
|
|
if (getComplexity(I.getOperand(0)) < getComplexity(I.getOperand(1)))
|
|
|
|
Changed = !I.swapOperands();
|
|
|
|
|
|
|
|
if (!I.isAssociative()) return Changed;
|
|
|
|
Instruction::BinaryOps Opcode = I.getOpcode();
|
2003-03-11 00:12:48 +00:00
|
|
|
if (BinaryOperator *Op = dyn_cast<BinaryOperator>(I.getOperand(0)))
|
|
|
|
if (Op->getOpcode() == Opcode && isa<Constant>(Op->getOperand(1))) {
|
|
|
|
if (isa<Constant>(I.getOperand(1))) {
|
2003-05-27 16:40:51 +00:00
|
|
|
Constant *Folded = ConstantExpr::get(I.getOpcode(),
|
|
|
|
cast<Constant>(I.getOperand(1)),
|
|
|
|
cast<Constant>(Op->getOperand(1)));
|
2003-03-11 00:12:48 +00:00
|
|
|
I.setOperand(0, Op->getOperand(0));
|
|
|
|
I.setOperand(1, Folded);
|
|
|
|
return true;
|
|
|
|
} else if (BinaryOperator *Op1=dyn_cast<BinaryOperator>(I.getOperand(1)))
|
|
|
|
if (Op1->getOpcode() == Opcode && isa<Constant>(Op1->getOperand(1)) &&
|
|
|
|
isOnlyUse(Op) && isOnlyUse(Op1)) {
|
|
|
|
Constant *C1 = cast<Constant>(Op->getOperand(1));
|
|
|
|
Constant *C2 = cast<Constant>(Op1->getOperand(1));
|
|
|
|
|
|
|
|
// Fold (op (op V1, C1), (op V2, C2)) ==> (op (op V1, V2), (op C1,C2))
|
2003-05-27 16:40:51 +00:00
|
|
|
Constant *Folded = ConstantExpr::get(I.getOpcode(), C1, C2);
|
2003-03-11 00:12:48 +00:00
|
|
|
Instruction *New = BinaryOperator::create(Opcode, Op->getOperand(0),
|
|
|
|
Op1->getOperand(0),
|
|
|
|
Op1->getName(), &I);
|
|
|
|
WorkList.push_back(New);
|
|
|
|
I.setOperand(0, New);
|
|
|
|
I.setOperand(1, Folded);
|
|
|
|
return true;
|
|
|
|
}
|
2003-03-10 21:43:22 +00:00
|
|
|
}
|
|
|
|
return Changed;
|
2002-04-18 17:39:14 +00:00
|
|
|
}
|
2001-12-14 16:52:21 +00:00
|
|
|
|
2003-03-10 23:06:50 +00:00
|
|
|
// dyn_castNegVal - Given a 'sub' instruction, return the RHS of the instruction
|
|
|
|
// if the LHS is a constant zero (which is the 'negate' form).
|
2002-05-06 16:49:18 +00:00
|
|
|
//
|
2003-03-10 23:06:50 +00:00
|
|
|
static inline Value *dyn_castNegVal(Value *V) {
|
|
|
|
if (BinaryOperator::isNeg(V))
|
|
|
|
return BinaryOperator::getNegArgument(cast<BinaryOperator>(V));
|
|
|
|
|
2003-04-30 22:19:10 +00:00
|
|
|
// Constants can be considered to be negated values if they can be folded...
|
|
|
|
if (Constant *C = dyn_cast<Constant>(V))
|
2004-12-08 22:20:34 +00:00
|
|
|
if (!isa<UndefValue>(C))
|
|
|
|
return ConstantExpr::getNeg(C);
|
2003-03-10 23:06:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline Value *dyn_castNotVal(Value *V) {
|
|
|
|
if (BinaryOperator::isNot(V))
|
|
|
|
return BinaryOperator::getNotArgument(cast<BinaryOperator>(V));
|
|
|
|
|
|
|
|
// Constants can be considered to be not'ed values...
|
2003-04-30 22:34:06 +00:00
|
|
|
if (ConstantIntegral *C = dyn_cast<ConstantIntegral>(V))
|
2004-06-10 02:12:35 +00:00
|
|
|
return ConstantExpr::getNot(C);
|
2003-03-10 23:06:50 +00:00
|
|
|
return 0;
|
2002-05-06 16:49:18 +00:00
|
|
|
}
|
|
|
|
|
2003-03-11 00:12:48 +00:00
|
|
|
// dyn_castFoldableMul - If this value is a multiply that can be folded into
|
|
|
|
// other computations (because it has a constant operand), return the
|
2004-11-13 19:50:12 +00:00
|
|
|
// non-constant operand of the multiply, and set CST to point to the multiplier.
|
|
|
|
// Otherwise, return null.
|
2003-03-11 00:12:48 +00:00
|
|
|
//
|
2004-11-13 19:50:12 +00:00
|
|
|
static inline Value *dyn_castFoldableMul(Value *V, ConstantInt *&CST) {
|
2003-10-15 16:48:29 +00:00
|
|
|
if (V->hasOneUse() && V->getType()->isInteger())
|
2004-11-13 19:50:12 +00:00
|
|
|
if (Instruction *I = dyn_cast<Instruction>(V)) {
|
2003-03-11 00:12:48 +00:00
|
|
|
if (I->getOpcode() == Instruction::Mul)
|
2004-11-15 05:54:07 +00:00
|
|
|
if ((CST = dyn_cast<ConstantInt>(I->getOperand(1))))
|
2003-03-11 00:12:48 +00:00
|
|
|
return I->getOperand(0);
|
2004-11-13 19:50:12 +00:00
|
|
|
if (I->getOpcode() == Instruction::Shl)
|
2004-11-15 05:54:07 +00:00
|
|
|
if ((CST = dyn_cast<ConstantInt>(I->getOperand(1)))) {
|
2004-11-13 19:50:12 +00:00
|
|
|
// The multiplier is really 1 << CST.
|
|
|
|
Constant *One = ConstantInt::get(V->getType(), 1);
|
|
|
|
CST = cast<ConstantInt>(ConstantExpr::getShl(One, CST));
|
|
|
|
return I->getOperand(0);
|
|
|
|
}
|
|
|
|
}
|
2003-03-11 00:12:48 +00:00
|
|
|
return 0;
|
2003-02-18 19:28:33 +00:00
|
|
|
}
|
2002-08-14 17:51:49 +00:00
|
|
|
|
2003-02-18 19:28:33 +00:00
|
|
|
// Log2 - Calculate the log base 2 for the specified value if it is exactly a
|
|
|
|
// power of 2.
|
|
|
|
static unsigned Log2(uint64_t Val) {
|
|
|
|
assert(Val > 1 && "Values 0 and 1 should be handled elsewhere!");
|
|
|
|
unsigned Count = 0;
|
|
|
|
while (Val != 1) {
|
|
|
|
if (Val & 1) return 0; // Multiple bits set?
|
|
|
|
Val >>= 1;
|
|
|
|
++Count;
|
|
|
|
}
|
|
|
|
return Count;
|
2002-08-14 17:51:49 +00:00
|
|
|
}
|
|
|
|
|
Fold (and (setcc X, C1), (setcc X, C2))
This is important for several reasons:
1. Benchmarks have lots of code that looks like this (perlbmk in particular):
%tmp.2.i = setne int %tmp.0.i, 128 ; <bool> [#uses=1]
%tmp.6343 = seteq int %tmp.0.i, 1 ; <bool> [#uses=1]
%tmp.63 = and bool %tmp.2.i, %tmp.6343 ; <bool> [#uses=1]
we now fold away the setne, a clear improvement.
2. In the more important cases, such as (X >= 10) & (X < 20), we now produce
smaller code: (X-10) < 10.
3. Perhaps the nicest effect of this patch is that it really helps out the
code generators. In particular, for a 'range test' like the above,
instead of generating this on X86 (the difference on PPC is even more
pronounced):
cmp %EAX, 50
setge %CL
cmp %EAX, 100
setl %AL
and %CL, %AL
cmp %CL, 0
we now generate this:
add %EAX, -50
cmp %EAX, 50
Furthermore, this causes setcc's to be folded into branches more often.
These combinations trigger dozens of times in the spec benchmarks, particularly
in 176.gcc, 186.crafty, 253.perlbmk, 254.gap, & 099.go.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16559 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-28 21:48:02 +00:00
|
|
|
// AddOne, SubOne - Add or subtract a constant one from an integer constant...
|
2004-09-29 17:40:11 +00:00
|
|
|
static ConstantInt *AddOne(ConstantInt *C) {
|
|
|
|
return cast<ConstantInt>(ConstantExpr::getAdd(C,
|
|
|
|
ConstantInt::get(C->getType(), 1)));
|
Fold (and (setcc X, C1), (setcc X, C2))
This is important for several reasons:
1. Benchmarks have lots of code that looks like this (perlbmk in particular):
%tmp.2.i = setne int %tmp.0.i, 128 ; <bool> [#uses=1]
%tmp.6343 = seteq int %tmp.0.i, 1 ; <bool> [#uses=1]
%tmp.63 = and bool %tmp.2.i, %tmp.6343 ; <bool> [#uses=1]
we now fold away the setne, a clear improvement.
2. In the more important cases, such as (X >= 10) & (X < 20), we now produce
smaller code: (X-10) < 10.
3. Perhaps the nicest effect of this patch is that it really helps out the
code generators. In particular, for a 'range test' like the above,
instead of generating this on X86 (the difference on PPC is even more
pronounced):
cmp %EAX, 50
setge %CL
cmp %EAX, 100
setl %AL
and %CL, %AL
cmp %CL, 0
we now generate this:
add %EAX, -50
cmp %EAX, 50
Furthermore, this causes setcc's to be folded into branches more often.
These combinations trigger dozens of times in the spec benchmarks, particularly
in 176.gcc, 186.crafty, 253.perlbmk, 254.gap, & 099.go.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16559 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-28 21:48:02 +00:00
|
|
|
}
|
2004-09-29 17:40:11 +00:00
|
|
|
static ConstantInt *SubOne(ConstantInt *C) {
|
|
|
|
return cast<ConstantInt>(ConstantExpr::getSub(C,
|
|
|
|
ConstantInt::get(C->getType(), 1)));
|
Fold (and (setcc X, C1), (setcc X, C2))
This is important for several reasons:
1. Benchmarks have lots of code that looks like this (perlbmk in particular):
%tmp.2.i = setne int %tmp.0.i, 128 ; <bool> [#uses=1]
%tmp.6343 = seteq int %tmp.0.i, 1 ; <bool> [#uses=1]
%tmp.63 = and bool %tmp.2.i, %tmp.6343 ; <bool> [#uses=1]
we now fold away the setne, a clear improvement.
2. In the more important cases, such as (X >= 10) & (X < 20), we now produce
smaller code: (X-10) < 10.
3. Perhaps the nicest effect of this patch is that it really helps out the
code generators. In particular, for a 'range test' like the above,
instead of generating this on X86 (the difference on PPC is even more
pronounced):
cmp %EAX, 50
setge %CL
cmp %EAX, 100
setl %AL
and %CL, %AL
cmp %CL, 0
we now generate this:
add %EAX, -50
cmp %EAX, 50
Furthermore, this causes setcc's to be folded into branches more often.
These combinations trigger dozens of times in the spec benchmarks, particularly
in 176.gcc, 186.crafty, 253.perlbmk, 254.gap, & 099.go.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16559 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-28 21:48:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// isTrueWhenEqual - Return true if the specified setcondinst instruction is
|
|
|
|
// true when both operands are equal...
|
|
|
|
//
|
|
|
|
static bool isTrueWhenEqual(Instruction &I) {
|
|
|
|
return I.getOpcode() == Instruction::SetEQ ||
|
|
|
|
I.getOpcode() == Instruction::SetGE ||
|
|
|
|
I.getOpcode() == Instruction::SetLE;
|
|
|
|
}
|
2003-08-13 19:01:45 +00:00
|
|
|
|
|
|
|
/// AssociativeOpt - Perform an optimization on an associative operator. This
|
|
|
|
/// function is designed to check a chain of associative operators for a
|
|
|
|
/// potential to apply a certain optimization. Since the optimization may be
|
|
|
|
/// applicable if the expression was reassociated, this checks the chain, then
|
|
|
|
/// reassociates the expression as necessary to expose the optimization
|
|
|
|
/// opportunity. This makes use of a special Functor, which must define
|
|
|
|
/// 'shouldApply' and 'apply' methods.
|
|
|
|
///
|
|
|
|
template<typename Functor>
|
|
|
|
Instruction *AssociativeOpt(BinaryOperator &Root, const Functor &F) {
|
|
|
|
unsigned Opcode = Root.getOpcode();
|
|
|
|
Value *LHS = Root.getOperand(0);
|
|
|
|
|
|
|
|
// Quick check, see if the immediate LHS matches...
|
|
|
|
if (F.shouldApply(LHS))
|
|
|
|
return F.apply(Root);
|
|
|
|
|
|
|
|
// Otherwise, if the LHS is not of the same opcode as the root, return.
|
|
|
|
Instruction *LHSI = dyn_cast<Instruction>(LHS);
|
2003-10-15 16:48:29 +00:00
|
|
|
while (LHSI && LHSI->getOpcode() == Opcode && LHSI->hasOneUse()) {
|
2003-08-13 19:01:45 +00:00
|
|
|
// Should we apply this transform to the RHS?
|
|
|
|
bool ShouldApply = F.shouldApply(LHSI->getOperand(1));
|
|
|
|
|
|
|
|
// If not to the RHS, check to see if we should apply to the LHS...
|
|
|
|
if (!ShouldApply && F.shouldApply(LHSI->getOperand(0))) {
|
|
|
|
cast<BinaryOperator>(LHSI)->swapOperands(); // Make the LHS the RHS
|
|
|
|
ShouldApply = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the functor wants to apply the optimization to the RHS of LHSI,
|
|
|
|
// reassociate the expression from ((? op A) op B) to (? op (A op B))
|
|
|
|
if (ShouldApply) {
|
|
|
|
BasicBlock *BB = Root.getParent();
|
|
|
|
|
|
|
|
// Now all of the instructions are in the current basic block, go ahead
|
|
|
|
// and perform the reassociation.
|
|
|
|
Instruction *TmpLHSI = cast<Instruction>(Root.getOperand(0));
|
|
|
|
|
|
|
|
// First move the selected RHS to the LHS of the root...
|
|
|
|
Root.setOperand(0, LHSI->getOperand(1));
|
|
|
|
|
|
|
|
// Make what used to be the LHS of the root be the user of the root...
|
|
|
|
Value *ExtraOperand = TmpLHSI->getOperand(1);
|
2004-04-16 18:08:07 +00:00
|
|
|
if (&Root == TmpLHSI) {
|
2004-04-05 02:10:19 +00:00
|
|
|
Root.replaceAllUsesWith(Constant::getNullValue(TmpLHSI->getType()));
|
|
|
|
return 0;
|
|
|
|
}
|
2004-04-16 18:08:07 +00:00
|
|
|
Root.replaceAllUsesWith(TmpLHSI); // Users now use TmpLHSI
|
2003-08-13 19:01:45 +00:00
|
|
|
TmpLHSI->setOperand(1, &Root); // TmpLHSI now uses the root
|
2004-04-16 18:08:07 +00:00
|
|
|
TmpLHSI->getParent()->getInstList().remove(TmpLHSI);
|
|
|
|
BasicBlock::iterator ARI = &Root; ++ARI;
|
|
|
|
BB->getInstList().insert(ARI, TmpLHSI); // Move TmpLHSI to after Root
|
|
|
|
ARI = Root;
|
2003-08-13 19:01:45 +00:00
|
|
|
|
|
|
|
// Now propagate the ExtraOperand down the chain of instructions until we
|
|
|
|
// get to LHSI.
|
|
|
|
while (TmpLHSI != LHSI) {
|
|
|
|
Instruction *NextLHSI = cast<Instruction>(TmpLHSI->getOperand(0));
|
2004-04-16 18:08:07 +00:00
|
|
|
// Move the instruction to immediately before the chain we are
|
|
|
|
// constructing to avoid breaking dominance properties.
|
|
|
|
NextLHSI->getParent()->getInstList().remove(NextLHSI);
|
|
|
|
BB->getInstList().insert(ARI, NextLHSI);
|
|
|
|
ARI = NextLHSI;
|
|
|
|
|
2003-08-13 19:01:45 +00:00
|
|
|
Value *NextOp = NextLHSI->getOperand(1);
|
|
|
|
NextLHSI->setOperand(1, ExtraOperand);
|
|
|
|
TmpLHSI = NextLHSI;
|
|
|
|
ExtraOperand = NextOp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now that the instructions are reassociated, have the functor perform
|
|
|
|
// the transformation...
|
|
|
|
return F.apply(Root);
|
|
|
|
}
|
|
|
|
|
|
|
|
LHSI = dyn_cast<Instruction>(LHSI->getOperand(0));
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// AddRHS - Implements: X + X --> X << 1
|
|
|
|
struct AddRHS {
|
|
|
|
Value *RHS;
|
|
|
|
AddRHS(Value *rhs) : RHS(rhs) {}
|
|
|
|
bool shouldApply(Value *LHS) const { return LHS == RHS; }
|
|
|
|
Instruction *apply(BinaryOperator &Add) const {
|
|
|
|
return new ShiftInst(Instruction::Shl, Add.getOperand(0),
|
|
|
|
ConstantInt::get(Type::UByteTy, 1));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// AddMaskingAnd - Implements (A & C1)+(B & C2) --> (A & C1)|(B & C2)
|
|
|
|
// iff C1&C2 == 0
|
|
|
|
struct AddMaskingAnd {
|
|
|
|
Constant *C2;
|
|
|
|
AddMaskingAnd(Constant *c) : C2(c) {}
|
|
|
|
bool shouldApply(Value *LHS) const {
|
2004-07-30 07:50:03 +00:00
|
|
|
ConstantInt *C1;
|
|
|
|
return match(LHS, m_And(m_Value(), m_ConstantInt(C1))) &&
|
|
|
|
ConstantExpr::getAnd(C1, C2)->isNullValue();
|
2003-08-13 19:01:45 +00:00
|
|
|
}
|
|
|
|
Instruction *apply(BinaryOperator &Add) const {
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createOr(Add.getOperand(0), Add.getOperand(1));
|
2003-08-13 19:01:45 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2004-04-09 19:05:30 +00:00
|
|
|
static Value *FoldOperationIntoSelectOperand(Instruction &BI, Value *SO,
|
|
|
|
InstCombiner *IC) {
|
|
|
|
// Figure out if the constant is the left or the right argument.
|
|
|
|
bool ConstIsRHS = isa<Constant>(BI.getOperand(1));
|
|
|
|
Constant *ConstOperand = cast<Constant>(BI.getOperand(ConstIsRHS));
|
|
|
|
|
|
|
|
if (Constant *SOC = dyn_cast<Constant>(SO)) {
|
|
|
|
if (ConstIsRHS)
|
|
|
|
return ConstantExpr::get(BI.getOpcode(), SOC, ConstOperand);
|
|
|
|
return ConstantExpr::get(BI.getOpcode(), ConstOperand, SOC);
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *Op0 = SO, *Op1 = ConstOperand;
|
|
|
|
if (!ConstIsRHS)
|
|
|
|
std::swap(Op0, Op1);
|
|
|
|
Instruction *New;
|
|
|
|
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&BI))
|
|
|
|
New = BinaryOperator::create(BO->getOpcode(), Op0, Op1);
|
|
|
|
else if (ShiftInst *SI = dyn_cast<ShiftInst>(&BI))
|
|
|
|
New = new ShiftInst(SI->getOpcode(), Op0, Op1);
|
2004-04-10 19:15:56 +00:00
|
|
|
else {
|
2004-04-09 19:05:30 +00:00
|
|
|
assert(0 && "Unknown binary instruction type!");
|
2004-04-10 19:15:56 +00:00
|
|
|
abort();
|
|
|
|
}
|
2004-04-09 19:05:30 +00:00
|
|
|
return IC->InsertNewInstBefore(New, BI);
|
|
|
|
}
|
2003-08-13 19:01:45 +00:00
|
|
|
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
|
|
|
|
/// FoldOpIntoPhi - Given a binary operator or cast instruction which has a PHI
|
|
|
|
/// node as operand #0, see if we can fold the instruction into the PHI (which
|
|
|
|
/// is only possible if all operands to the PHI are constants).
|
|
|
|
Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
|
|
|
|
PHINode *PN = cast<PHINode>(I.getOperand(0));
|
2004-11-14 19:13:23 +00:00
|
|
|
unsigned NumPHIValues = PN->getNumIncomingValues();
|
|
|
|
if (!PN->hasOneUse() || NumPHIValues == 0 ||
|
|
|
|
!isa<Constant>(PN->getIncomingValue(0))) return 0;
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
|
|
|
|
// Check to see if all of the operands of the PHI are constants. If not, we
|
|
|
|
// cannot do the transformation.
|
2004-11-14 19:13:23 +00:00
|
|
|
for (unsigned i = 1; i != NumPHIValues; ++i)
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
if (!isa<Constant>(PN->getIncomingValue(i)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// Okay, we can do the transformation: create the new PHI node.
|
|
|
|
PHINode *NewPN = new PHINode(I.getType(), I.getName());
|
|
|
|
I.setName("");
|
|
|
|
NewPN->op_reserve(PN->getNumOperands());
|
|
|
|
InsertNewInstBefore(NewPN, *PN);
|
|
|
|
|
|
|
|
// Next, add all of the operands to the PHI.
|
|
|
|
if (I.getNumOperands() == 2) {
|
|
|
|
Constant *C = cast<Constant>(I.getOperand(1));
|
2004-11-14 19:13:23 +00:00
|
|
|
for (unsigned i = 0; i != NumPHIValues; ++i) {
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
Constant *InV = cast<Constant>(PN->getIncomingValue(i));
|
|
|
|
NewPN->addIncoming(ConstantExpr::get(I.getOpcode(), InV, C),
|
|
|
|
PN->getIncomingBlock(i));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
assert(isa<CastInst>(I) && "Unary op should be a cast!");
|
|
|
|
const Type *RetTy = I.getType();
|
2004-11-14 19:13:23 +00:00
|
|
|
for (unsigned i = 0; i != NumPHIValues; ++i) {
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
Constant *InV = cast<Constant>(PN->getIncomingValue(i));
|
|
|
|
NewPN->addIncoming(ConstantExpr::getCast(InV, RetTy),
|
|
|
|
PN->getIncomingBlock(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ReplaceInstUsesWith(I, NewPN);
|
|
|
|
}
|
|
|
|
|
2004-04-09 19:05:30 +00:00
|
|
|
// FoldBinOpIntoSelect - Given an instruction with a select as one operand and a
|
|
|
|
// constant as the other operand, try to fold the binary operator into the
|
|
|
|
// select arguments.
|
|
|
|
static Instruction *FoldBinOpIntoSelect(Instruction &BI, SelectInst *SI,
|
|
|
|
InstCombiner *IC) {
|
|
|
|
// Don't modify shared select instructions
|
|
|
|
if (!SI->hasOneUse()) return 0;
|
|
|
|
Value *TV = SI->getOperand(1);
|
|
|
|
Value *FV = SI->getOperand(2);
|
|
|
|
|
|
|
|
if (isa<Constant>(TV) || isa<Constant>(FV)) {
|
|
|
|
Value *SelectTrueVal = FoldOperationIntoSelectOperand(BI, TV, IC);
|
|
|
|
Value *SelectFalseVal = FoldOperationIntoSelectOperand(BI, FV, IC);
|
|
|
|
|
|
|
|
return new SelectInst(SI->getCondition(), SelectTrueVal,
|
|
|
|
SelectFalseVal);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2003-08-13 19:01:45 +00:00
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
2003-03-10 21:43:22 +00:00
|
|
|
bool Changed = SimplifyCommutative(I);
|
2002-06-25 16:13:24 +00:00
|
|
|
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
2002-05-06 16:49:18 +00:00
|
|
|
|
2004-04-10 22:01:55 +00:00
|
|
|
if (Constant *RHSC = dyn_cast<Constant>(RHS)) {
|
2004-10-16 18:11:37 +00:00
|
|
|
// X + undef -> undef
|
|
|
|
if (isa<UndefValue>(RHS))
|
|
|
|
return ReplaceInstUsesWith(I, RHS);
|
|
|
|
|
2004-04-10 22:01:55 +00:00
|
|
|
// X + 0 --> X
|
|
|
|
if (!I.getType()->isFloatingPoint() && // -0 + +0 = +0, so it's not a noop
|
|
|
|
RHSC->isNullValue())
|
|
|
|
return ReplaceInstUsesWith(I, LHS);
|
|
|
|
|
|
|
|
// X + (signbit) --> X ^ signbit
|
|
|
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHSC)) {
|
|
|
|
unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
|
|
|
|
uint64_t Val = CI->getRawValue() & (1ULL << NumBits)-1;
|
2004-11-05 04:45:43 +00:00
|
|
|
if (Val == (1ULL << (NumBits-1)))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createXor(LHS, RHS);
|
2004-04-10 22:01:55 +00:00
|
|
|
}
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
|
|
|
|
if (isa<PHINode>(LHS))
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
2004-04-10 22:01:55 +00:00
|
|
|
}
|
2002-05-06 16:49:18 +00:00
|
|
|
|
2003-08-13 19:01:45 +00:00
|
|
|
// X + X --> X << 1
|
2004-07-27 21:02:21 +00:00
|
|
|
if (I.getType()->isInteger()) {
|
2003-08-13 19:01:45 +00:00
|
|
|
if (Instruction *Result = AssociativeOpt(I, AddRHS(RHS))) return Result;
|
2004-07-27 21:02:21 +00:00
|
|
|
}
|
2003-08-13 04:18:28 +00:00
|
|
|
|
2002-05-08 22:46:53 +00:00
|
|
|
// -A + B --> B - A
|
2003-03-10 23:06:50 +00:00
|
|
|
if (Value *V = dyn_castNegVal(LHS))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSub(RHS, V);
|
2002-05-06 16:49:18 +00:00
|
|
|
|
|
|
|
// A + -B --> A - B
|
2003-03-10 23:06:50 +00:00
|
|
|
if (!isa<Constant>(RHS))
|
|
|
|
if (Value *V = dyn_castNegVal(RHS))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSub(LHS, V);
|
2002-04-18 17:39:14 +00:00
|
|
|
|
2004-11-13 19:50:12 +00:00
|
|
|
ConstantInt *C2;
|
|
|
|
if (Value *X = dyn_castFoldableMul(LHS, C2)) {
|
|
|
|
if (X == RHS) // X*C + X --> X * (C+1)
|
|
|
|
return BinaryOperator::createMul(RHS, AddOne(C2));
|
|
|
|
|
|
|
|
// X*C1 + X*C2 --> X * (C1+C2)
|
|
|
|
ConstantInt *C1;
|
|
|
|
if (X == dyn_castFoldableMul(RHS, C1))
|
|
|
|
return BinaryOperator::createMul(X, ConstantExpr::getAdd(C1, C2));
|
2003-02-18 19:57:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// X + X*C --> X * (C+1)
|
2004-11-13 19:50:12 +00:00
|
|
|
if (dyn_castFoldableMul(RHS, C2) == LHS)
|
|
|
|
return BinaryOperator::createMul(LHS, AddOne(C2));
|
|
|
|
|
2003-02-18 19:57:07 +00:00
|
|
|
|
2003-08-13 19:01:45 +00:00
|
|
|
// (A & C1)+(B & C2) --> (A & C1)|(B & C2) iff C1&C2 == 0
|
2004-07-30 07:50:03 +00:00
|
|
|
if (match(RHS, m_And(m_Value(), m_ConstantInt(C2))))
|
2003-08-13 19:01:45 +00:00
|
|
|
if (Instruction *R = AssociativeOpt(I, AddMaskingAnd(C2))) return R;
|
2003-03-11 00:12:48 +00:00
|
|
|
|
2003-10-02 15:11:26 +00:00
|
|
|
if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
|
2004-07-30 07:50:03 +00:00
|
|
|
Value *X;
|
|
|
|
if (match(LHS, m_Not(m_Value(X)))) { // ~X + C --> (C-1) - X
|
|
|
|
Constant *C= ConstantExpr::getSub(CRHS, ConstantInt::get(I.getType(), 1));
|
|
|
|
return BinaryOperator::createSub(C, X);
|
2003-10-02 15:11:26 +00:00
|
|
|
}
|
2004-07-30 07:50:03 +00:00
|
|
|
|
2004-10-08 05:07:56 +00:00
|
|
|
// (X & FF00) + xx00 -> (X+xx00) & FF00
|
|
|
|
if (LHS->hasOneUse() && match(LHS, m_And(m_Value(X), m_ConstantInt(C2)))) {
|
|
|
|
Constant *Anded = ConstantExpr::getAnd(CRHS, C2);
|
|
|
|
if (Anded == CRHS) {
|
|
|
|
// See if all bits from the first bit set in the Add RHS up are included
|
|
|
|
// in the mask. First, get the rightmost bit.
|
|
|
|
uint64_t AddRHSV = CRHS->getRawValue();
|
|
|
|
|
|
|
|
// Form a mask of all bits from the lowest bit added through the top.
|
|
|
|
uint64_t AddRHSHighBits = ~((AddRHSV & -AddRHSV)-1);
|
|
|
|
AddRHSHighBits &= (1ULL << C2->getType()->getPrimitiveSize()*8)-1;
|
|
|
|
|
|
|
|
// See if the and mask includes all of these bits.
|
|
|
|
uint64_t AddRHSHighBitsAnd = AddRHSHighBits & C2->getRawValue();
|
|
|
|
|
|
|
|
if (AddRHSHighBits == AddRHSHighBitsAnd) {
|
|
|
|
// Okay, the xform is safe. Insert the new add pronto.
|
|
|
|
Value *NewAdd = InsertNewInstBefore(BinaryOperator::createAdd(X, CRHS,
|
|
|
|
LHS->getName()), I);
|
|
|
|
return BinaryOperator::createAnd(NewAdd, C2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-30 07:50:03 +00:00
|
|
|
// Try to fold constant add into select arguments.
|
|
|
|
if (SelectInst *SI = dyn_cast<SelectInst>(LHS))
|
|
|
|
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
|
|
|
|
return R;
|
2003-10-02 15:11:26 +00:00
|
|
|
}
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
return Changed ? &I : 0;
|
2002-04-18 17:39:14 +00:00
|
|
|
}
|
2002-02-26 21:46:54 +00:00
|
|
|
|
2003-07-22 21:46:59 +00:00
|
|
|
// isSignBit - Return true if the value represented by the constant only has the
|
|
|
|
// highest order bit set.
|
|
|
|
static bool isSignBit(ConstantInt *CI) {
|
|
|
|
unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
|
|
|
|
return (CI->getRawValue() & ~(-1LL << NumBits)) == (1ULL << (NumBits-1));
|
|
|
|
}
|
|
|
|
|
2003-07-24 17:35:25 +00:00
|
|
|
static unsigned getTypeSizeInBits(const Type *Ty) {
|
|
|
|
return Ty == Type::BoolTy ? 1 : Ty->getPrimitiveSize()*8;
|
|
|
|
}
|
|
|
|
|
2004-03-13 00:11:49 +00:00
|
|
|
/// RemoveNoopCast - Strip off nonconverting casts from the value.
|
|
|
|
///
|
|
|
|
static Value *RemoveNoopCast(Value *V) {
|
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(V)) {
|
|
|
|
const Type *CTy = CI->getType();
|
|
|
|
const Type *OpTy = CI->getOperand(0)->getType();
|
|
|
|
if (CTy->isInteger() && OpTy->isInteger()) {
|
|
|
|
if (CTy->getPrimitiveSize() == OpTy->getPrimitiveSize())
|
|
|
|
return RemoveNoopCast(CI->getOperand(0));
|
|
|
|
} else if (isa<PointerType>(CTy) && isa<PointerType>(OpTy))
|
|
|
|
return RemoveNoopCast(CI->getOperand(0));
|
|
|
|
}
|
|
|
|
return V;
|
|
|
|
}
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
|
|
|
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2002-08-12 21:17:25 +00:00
|
|
|
if (Op0 == Op1) // sub X, X -> 0
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
2002-04-18 17:39:14 +00:00
|
|
|
|
2002-08-12 21:17:25 +00:00
|
|
|
// If this is a 'B = x-(-A)', change to B = x+A...
|
2003-03-10 23:06:50 +00:00
|
|
|
if (Value *V = dyn_castNegVal(Op1))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAdd(Op0, V);
|
2002-05-06 16:49:18 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(Op0))
|
|
|
|
return ReplaceInstUsesWith(I, Op0); // undef - X -> undef
|
|
|
|
if (isa<UndefValue>(Op1))
|
|
|
|
return ReplaceInstUsesWith(I, Op1); // X - undef -> undef
|
|
|
|
|
2003-11-05 01:06:05 +00:00
|
|
|
if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) {
|
|
|
|
// Replace (-1 - A) with (~A)...
|
2003-02-18 19:28:33 +00:00
|
|
|
if (C->isAllOnesValue())
|
|
|
|
return BinaryOperator::createNot(Op1);
|
|
|
|
|
2003-11-05 01:06:05 +00:00
|
|
|
// C - ~X == X + (1+C)
|
2004-07-30 07:50:03 +00:00
|
|
|
Value *X;
|
|
|
|
if (match(Op1, m_Not(m_Value(X))))
|
|
|
|
return BinaryOperator::createAdd(X,
|
2004-06-10 02:07:29 +00:00
|
|
|
ConstantExpr::getAdd(C, ConstantInt::get(I.getType(), 1)));
|
2004-03-12 23:53:13 +00:00
|
|
|
// -((uint)X >> 31) -> ((int)X >> 31)
|
|
|
|
// -((int)X >> 31) -> ((uint)X >> 31)
|
2004-03-13 00:11:49 +00:00
|
|
|
if (C->isNullValue()) {
|
|
|
|
Value *NoopCastedRHS = RemoveNoopCast(Op1);
|
|
|
|
if (ShiftInst *SI = dyn_cast<ShiftInst>(NoopCastedRHS))
|
2004-03-12 23:53:13 +00:00
|
|
|
if (SI->getOpcode() == Instruction::Shr)
|
|
|
|
if (ConstantUInt *CU = dyn_cast<ConstantUInt>(SI->getOperand(1))) {
|
|
|
|
const Type *NewTy;
|
2004-03-13 00:11:49 +00:00
|
|
|
if (SI->getType()->isSigned())
|
2004-06-17 18:16:02 +00:00
|
|
|
NewTy = SI->getType()->getUnsignedVersion();
|
2004-03-12 23:53:13 +00:00
|
|
|
else
|
2004-06-17 18:16:02 +00:00
|
|
|
NewTy = SI->getType()->getSignedVersion();
|
2004-03-12 23:53:13 +00:00
|
|
|
// Check to see if we are shifting out everything but the sign bit.
|
2004-03-13 00:11:49 +00:00
|
|
|
if (CU->getValue() == SI->getType()->getPrimitiveSize()*8-1) {
|
2004-03-12 23:53:13 +00:00
|
|
|
// Ok, the transformation is safe. Insert a cast of the incoming
|
|
|
|
// value, then the new shift, then the new cast.
|
|
|
|
Instruction *FirstCast = new CastInst(SI->getOperand(0), NewTy,
|
|
|
|
SI->getOperand(0)->getName());
|
|
|
|
Value *InV = InsertNewInstBefore(FirstCast, I);
|
|
|
|
Instruction *NewShift = new ShiftInst(Instruction::Shr, FirstCast,
|
|
|
|
CU, SI->getName());
|
2004-03-13 00:11:49 +00:00
|
|
|
if (NewShift->getType() == I.getType())
|
|
|
|
return NewShift;
|
|
|
|
else {
|
|
|
|
InV = InsertNewInstBefore(NewShift, I);
|
|
|
|
return new CastInst(NewShift, I.getType());
|
|
|
|
}
|
2004-03-12 23:53:13 +00:00
|
|
|
}
|
|
|
|
}
|
2004-03-13 00:11:49 +00:00
|
|
|
}
|
2004-04-09 19:05:30 +00:00
|
|
|
|
|
|
|
// Try to fold constant sub into select arguments.
|
|
|
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
|
|
|
|
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
|
|
|
|
return R;
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
|
|
|
|
if (isa<PHINode>(Op0))
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
2003-11-05 01:06:05 +00:00
|
|
|
}
|
|
|
|
|
2002-05-09 01:29:19 +00:00
|
|
|
if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1))
|
2003-10-15 16:48:29 +00:00
|
|
|
if (Op1I->hasOneUse()) {
|
2003-02-18 19:28:33 +00:00
|
|
|
// Replace (x - (y - z)) with (x + (z - y)) if the (y - z) subexpression
|
|
|
|
// is not used by anyone else...
|
|
|
|
//
|
2004-02-02 20:09:56 +00:00
|
|
|
if (Op1I->getOpcode() == Instruction::Sub &&
|
|
|
|
!Op1I->getType()->isFloatingPoint()) {
|
2003-02-18 19:28:33 +00:00
|
|
|
// Swap the two operands of the subexpr...
|
|
|
|
Value *IIOp0 = Op1I->getOperand(0), *IIOp1 = Op1I->getOperand(1);
|
|
|
|
Op1I->setOperand(0, IIOp1);
|
|
|
|
Op1I->setOperand(1, IIOp0);
|
|
|
|
|
|
|
|
// Create the new top level add instruction...
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAdd(Op0, Op1);
|
2003-02-18 19:28:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Replace (A - (A & B)) with (A & ~B) if this is the only use of (A&B)...
|
|
|
|
//
|
|
|
|
if (Op1I->getOpcode() == Instruction::And &&
|
|
|
|
(Op1I->getOperand(0) == Op0 || Op1I->getOperand(1) == Op0)) {
|
|
|
|
Value *OtherOp = Op1I->getOperand(Op1I->getOperand(0) == Op0);
|
|
|
|
|
Be more careful about the order we put stuff onto the worklist. This allow us to
collapse this:
bool %le(int %A, int %B) {
%c1 = setgt int %A, %B
%tmp = select bool %c1, int 1, int 0
%c2 = setlt int %A, %B
%result = select bool %c2, int -1, int %tmp
%c3 = setle int %result, 0
ret bool %c3
}
into:
bool %le(int %A, int %B) {
%c3 = setle int %A, %B ; <bool> [#uses=1]
ret bool %c3
}
which is handy, because the Java FE makes these sequences all over the place.
This is tested as: test/Regression/Transforms/InstCombine/JavaCompare.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14086 91177308-0d34-0410-b5e6-96231b3b80d8
2004-06-09 05:08:07 +00:00
|
|
|
Value *NewNot =
|
|
|
|
InsertNewInstBefore(BinaryOperator::createNot(OtherOp, "B.not"), I);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(Op0, NewNot);
|
2003-02-18 19:28:33 +00:00
|
|
|
}
|
2003-02-18 19:57:07 +00:00
|
|
|
|
2004-10-06 15:08:25 +00:00
|
|
|
// -(X sdiv C) -> (X sdiv -C)
|
|
|
|
if (Op1I->getOpcode() == Instruction::Div)
|
|
|
|
if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0))
|
|
|
|
if (CSI->getValue() == 0)
|
|
|
|
if (Constant *DivRHS = dyn_cast<Constant>(Op1I->getOperand(1)))
|
|
|
|
return BinaryOperator::createDiv(Op1I->getOperand(0),
|
|
|
|
ConstantExpr::getNeg(DivRHS));
|
|
|
|
|
2003-02-18 19:57:07 +00:00
|
|
|
// X - X*C --> X * (1-C)
|
2004-11-13 19:50:12 +00:00
|
|
|
ConstantInt *C2;
|
|
|
|
if (dyn_castFoldableMul(Op1I, C2) == Op0) {
|
|
|
|
Constant *CP1 =
|
|
|
|
ConstantExpr::getSub(ConstantInt::get(I.getType(), 1), C2);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createMul(Op0, CP1);
|
2003-02-18 19:57:07 +00:00
|
|
|
}
|
2002-05-09 01:29:19 +00:00
|
|
|
}
|
2003-02-18 19:28:33 +00:00
|
|
|
|
2004-11-13 19:50:12 +00:00
|
|
|
|
|
|
|
ConstantInt *C1;
|
|
|
|
if (Value *X = dyn_castFoldableMul(Op0, C1)) {
|
|
|
|
if (X == Op1) { // X*C - X --> X * (C-1)
|
|
|
|
Constant *CP1 = ConstantExpr::getSub(C1, ConstantInt::get(I.getType(),1));
|
|
|
|
return BinaryOperator::createMul(Op1, CP1);
|
|
|
|
}
|
2003-02-18 19:57:07 +00:00
|
|
|
|
2004-11-13 19:50:12 +00:00
|
|
|
ConstantInt *C2; // X*C1 - X*C2 -> X * (C1-C2)
|
|
|
|
if (X == dyn_castFoldableMul(Op1, C2))
|
|
|
|
return BinaryOperator::createMul(Op1, ConstantExpr::getSub(C1, C2));
|
|
|
|
}
|
2002-05-06 16:14:14 +00:00
|
|
|
return 0;
|
2002-04-18 17:39:14 +00:00
|
|
|
}
|
|
|
|
|
2004-02-23 06:38:22 +00:00
|
|
|
/// isSignBitCheck - Given an exploded setcc instruction, return true if it is
|
|
|
|
/// really just returns true if the most significant (sign) bit is set.
|
|
|
|
static bool isSignBitCheck(unsigned Opcode, Value *LHS, ConstantInt *RHS) {
|
|
|
|
if (RHS->getType()->isSigned()) {
|
|
|
|
// True if source is LHS < 0 or LHS <= -1
|
|
|
|
return Opcode == Instruction::SetLT && RHS->isNullValue() ||
|
|
|
|
Opcode == Instruction::SetLE && RHS->isAllOnesValue();
|
|
|
|
} else {
|
|
|
|
ConstantUInt *RHSC = cast<ConstantUInt>(RHS);
|
|
|
|
// True if source is LHS > 127 or LHS >= 128, where the constants depend on
|
|
|
|
// the size of the integer type.
|
|
|
|
if (Opcode == Instruction::SetGE)
|
|
|
|
return RHSC->getValue() == 1ULL<<(RHS->getType()->getPrimitiveSize()*8-1);
|
|
|
|
if (Opcode == Instruction::SetGT)
|
|
|
|
return RHSC->getValue() ==
|
|
|
|
(1ULL << (RHS->getType()->getPrimitiveSize()*8-1))-1;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
2003-03-10 21:43:22 +00:00
|
|
|
bool Changed = SimplifyCommutative(I);
|
2003-02-18 19:28:33 +00:00
|
|
|
Value *Op0 = I.getOperand(0);
|
2002-04-18 17:39:14 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(I.getOperand(1))) // undef * X -> 0
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
|
|
|
2002-08-12 21:17:25 +00:00
|
|
|
// Simplify mul instructions with a constant RHS...
|
2003-02-18 19:28:33 +00:00
|
|
|
if (Constant *Op1 = dyn_cast<Constant>(I.getOperand(1))) {
|
|
|
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
2003-08-13 04:18:28 +00:00
|
|
|
|
|
|
|
// ((X << C1)*C2) == (X * (C2 << C1))
|
|
|
|
if (ShiftInst *SI = dyn_cast<ShiftInst>(Op0))
|
|
|
|
if (SI->getOpcode() == Instruction::Shl)
|
|
|
|
if (Constant *ShOp = dyn_cast<Constant>(SI->getOperand(1)))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createMul(SI->getOperand(0),
|
|
|
|
ConstantExpr::getShl(CI, ShOp));
|
2004-01-12 19:35:11 +00:00
|
|
|
|
2003-09-11 22:24:54 +00:00
|
|
|
if (CI->isNullValue())
|
|
|
|
return ReplaceInstUsesWith(I, Op1); // X * 0 == 0
|
|
|
|
if (CI->equalsInt(1)) // X * 1 == X
|
|
|
|
return ReplaceInstUsesWith(I, Op0);
|
|
|
|
if (CI->isAllOnesValue()) // X * -1 == 0 - X
|
2003-06-25 17:09:20 +00:00
|
|
|
return BinaryOperator::createNeg(Op0, I.getName());
|
2002-04-29 22:24:47 +00:00
|
|
|
|
2003-09-11 22:24:54 +00:00
|
|
|
int64_t Val = (int64_t)cast<ConstantInt>(CI)->getRawValue();
|
2003-02-18 19:28:33 +00:00
|
|
|
if (uint64_t C = Log2(Val)) // Replace X*(2^C) with X << C
|
|
|
|
return new ShiftInst(Instruction::Shl, Op0,
|
|
|
|
ConstantUInt::get(Type::UByteTy, C));
|
2004-07-27 21:02:21 +00:00
|
|
|
} else if (ConstantFP *Op1F = dyn_cast<ConstantFP>(Op1)) {
|
2003-02-18 19:28:33 +00:00
|
|
|
if (Op1F->isNullValue())
|
|
|
|
return ReplaceInstUsesWith(I, Op1);
|
|
|
|
|
|
|
|
// "In IEEE floating point, x*1 is not equivalent to x for nans. However,
|
|
|
|
// ANSI says we can drop signals, so we can do this anyway." (from GCC)
|
|
|
|
if (Op1F->getValue() == 1.0)
|
|
|
|
return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul double %X, 1.0'
|
|
|
|
}
|
2004-04-09 19:05:30 +00:00
|
|
|
|
|
|
|
// Try to fold constant mul into select arguments.
|
|
|
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
|
|
|
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
|
|
|
|
return R;
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
|
|
|
|
if (isa<PHINode>(Op0))
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
2001-12-14 16:52:21 +00:00
|
|
|
}
|
|
|
|
|
2003-03-10 23:23:04 +00:00
|
|
|
if (Value *Op0v = dyn_castNegVal(Op0)) // -X * -Y = X*Y
|
|
|
|
if (Value *Op1v = dyn_castNegVal(I.getOperand(1)))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createMul(Op0v, Op1v);
|
2003-03-10 23:23:04 +00:00
|
|
|
|
2004-02-23 05:39:21 +00:00
|
|
|
// If one of the operands of the multiply is a cast from a boolean value, then
|
|
|
|
// we know the bool is either zero or one, so this is a 'masking' multiply.
|
|
|
|
// See if we can simplify things based on how the boolean was originally
|
|
|
|
// formed.
|
|
|
|
CastInst *BoolCast = 0;
|
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(I.getOperand(0)))
|
|
|
|
if (CI->getOperand(0)->getType() == Type::BoolTy)
|
|
|
|
BoolCast = CI;
|
|
|
|
if (!BoolCast)
|
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(I.getOperand(1)))
|
|
|
|
if (CI->getOperand(0)->getType() == Type::BoolTy)
|
|
|
|
BoolCast = CI;
|
|
|
|
if (BoolCast) {
|
|
|
|
if (SetCondInst *SCI = dyn_cast<SetCondInst>(BoolCast->getOperand(0))) {
|
|
|
|
Value *SCIOp0 = SCI->getOperand(0), *SCIOp1 = SCI->getOperand(1);
|
|
|
|
const Type *SCOpTy = SCIOp0->getType();
|
|
|
|
|
2004-02-23 06:38:22 +00:00
|
|
|
// If the setcc is true iff the sign bit of X is set, then convert this
|
|
|
|
// multiply into a shift/and combination.
|
|
|
|
if (isa<ConstantInt>(SCIOp1) &&
|
|
|
|
isSignBitCheck(SCI->getOpcode(), SCIOp0, cast<ConstantInt>(SCIOp1))) {
|
2004-02-23 05:39:21 +00:00
|
|
|
// Shift the X value right to turn it into "all signbits".
|
|
|
|
Constant *Amt = ConstantUInt::get(Type::UByteTy,
|
|
|
|
SCOpTy->getPrimitiveSize()*8-1);
|
2004-02-23 06:38:22 +00:00
|
|
|
if (SCIOp0->getType()->isUnsigned()) {
|
2004-06-17 18:16:02 +00:00
|
|
|
const Type *NewTy = SCIOp0->getType()->getSignedVersion();
|
2004-02-23 06:38:22 +00:00
|
|
|
SCIOp0 = InsertNewInstBefore(new CastInst(SCIOp0, NewTy,
|
|
|
|
SCIOp0->getName()), I);
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *V =
|
|
|
|
InsertNewInstBefore(new ShiftInst(Instruction::Shr, SCIOp0, Amt,
|
|
|
|
BoolCast->getOperand(0)->getName()+
|
|
|
|
".mask"), I);
|
2004-02-23 05:39:21 +00:00
|
|
|
|
|
|
|
// If the multiply type is not the same as the source type, sign extend
|
|
|
|
// or truncate to the multiply type.
|
|
|
|
if (I.getType() != V->getType())
|
2004-02-23 06:38:22 +00:00
|
|
|
V = InsertNewInstBefore(new CastInst(V, I.getType(), V->getName()),I);
|
2004-02-23 05:39:21 +00:00
|
|
|
|
|
|
|
Value *OtherOp = Op0 == BoolCast ? I.getOperand(1) : Op0;
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(V, OtherOp);
|
2004-02-23 05:39:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
return Changed ? &I : 0;
|
2002-04-18 17:39:14 +00:00
|
|
|
}
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(I.getOperand(0))) // undef / X -> 0
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
|
|
if (isa<UndefValue>(I.getOperand(1)))
|
|
|
|
return ReplaceInstUsesWith(I, I.getOperand(1)); // X / undef -> undef
|
|
|
|
|
2003-02-18 19:28:33 +00:00
|
|
|
if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1))) {
|
2004-04-26 14:01:59 +00:00
|
|
|
// div X, 1 == X
|
2002-08-12 21:17:25 +00:00
|
|
|
if (RHS->equalsInt(1))
|
|
|
|
return ReplaceInstUsesWith(I, I.getOperand(0));
|
2003-02-18 19:28:33 +00:00
|
|
|
|
2004-04-26 14:01:59 +00:00
|
|
|
// div X, -1 == -X
|
|
|
|
if (RHS->isAllOnesValue())
|
|
|
|
return BinaryOperator::createNeg(I.getOperand(0));
|
|
|
|
|
2004-09-28 18:22:15 +00:00
|
|
|
if (Instruction *LHS = dyn_cast<Instruction>(I.getOperand(0)))
|
|
|
|
if (LHS->getOpcode() == Instruction::Div)
|
|
|
|
if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) {
|
|
|
|
// (X / C1) / C2 -> X / (C1*C2)
|
|
|
|
return BinaryOperator::createDiv(LHS->getOperand(0),
|
|
|
|
ConstantExpr::getMul(RHS, LHSRHS));
|
|
|
|
}
|
|
|
|
|
2003-02-18 19:28:33 +00:00
|
|
|
// Check to see if this is an unsigned division with an exact power of 2,
|
|
|
|
// if so, convert to a right shift.
|
|
|
|
if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
|
|
|
|
if (uint64_t Val = C->getValue()) // Don't break X / 0
|
|
|
|
if (uint64_t C = Log2(Val))
|
|
|
|
return new ShiftInst(Instruction::Shr, I.getOperand(0),
|
|
|
|
ConstantUInt::get(Type::UByteTy, C));
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
|
2004-10-09 02:50:40 +00:00
|
|
|
// -X/C -> X/-C
|
|
|
|
if (RHS->getType()->isSigned())
|
|
|
|
if (Value *LHSNeg = dyn_castNegVal(I.getOperand(0)))
|
|
|
|
return BinaryOperator::createDiv(LHSNeg, ConstantExpr::getNeg(RHS));
|
|
|
|
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
if (isa<PHINode>(I.getOperand(0)) && !RHS->isNullValue())
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
2003-02-18 19:28:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0 / X == 0, we don't need to preserve faults!
|
|
|
|
if (ConstantInt *LHS = dyn_cast<ConstantInt>(I.getOperand(0)))
|
|
|
|
if (LHS->equalsInt(0))
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
|
|
|
2002-05-06 16:14:14 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitRem(BinaryOperator &I) {
|
2004-07-06 07:01:22 +00:00
|
|
|
if (I.getType()->isSigned())
|
|
|
|
if (Value *RHSNeg = dyn_castNegVal(I.getOperand(1)))
|
2004-07-06 07:11:42 +00:00
|
|
|
if (!isa<ConstantSInt>(RHSNeg) ||
|
2004-08-09 21:05:48 +00:00
|
|
|
cast<ConstantSInt>(RHSNeg)->getValue() > 0) {
|
2004-07-06 07:01:22 +00:00
|
|
|
// X % -Y -> X % Y
|
|
|
|
AddUsesToWorkList(I);
|
|
|
|
I.setOperand(1, RHSNeg);
|
|
|
|
return &I;
|
|
|
|
}
|
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(I.getOperand(0))) // undef % X -> 0
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
|
|
if (isa<UndefValue>(I.getOperand(1)))
|
|
|
|
return ReplaceInstUsesWith(I, I.getOperand(1)); // X % undef -> undef
|
|
|
|
|
2003-02-18 19:28:33 +00:00
|
|
|
if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1))) {
|
|
|
|
if (RHS->equalsInt(1)) // X % 1 == 0
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
|
|
|
|
|
|
// Check to see if this is an unsigned remainder with an exact power of 2,
|
|
|
|
// if so, convert to a bitwise and.
|
|
|
|
if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
|
|
|
|
if (uint64_t Val = C->getValue()) // Don't break X % 0 (divide by zero)
|
2004-05-07 15:35:56 +00:00
|
|
|
if (!(Val & (Val-1))) // Power of 2
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(I.getOperand(0),
|
2003-02-18 19:28:33 +00:00
|
|
|
ConstantUInt::get(I.getType(), Val-1));
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
if (isa<PHINode>(I.getOperand(0)) && !RHS->isNullValue())
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
2003-02-18 19:28:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0 % X == 0, we don't need to preserve faults!
|
|
|
|
if (ConstantInt *LHS = dyn_cast<ConstantInt>(I.getOperand(0)))
|
|
|
|
if (LHS->equalsInt(0))
|
2002-08-12 21:17:25 +00:00
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
2002-08-09 23:47:40 +00:00
|
|
|
|
2002-08-12 21:17:25 +00:00
|
|
|
return 0;
|
2002-08-09 23:47:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// isMaxValueMinusOne - return true if this is Max-1
|
2002-08-12 21:17:25 +00:00
|
|
|
static bool isMaxValueMinusOne(const ConstantInt *C) {
|
2002-08-09 23:47:40 +00:00
|
|
|
if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(C)) {
|
|
|
|
// Calculate -1 casted to the right type...
|
|
|
|
unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
|
|
|
|
uint64_t Val = ~0ULL; // All ones
|
|
|
|
Val >>= 64-TypeBits; // Shift out unwanted 1 bits...
|
|
|
|
return CU->getValue() == Val-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const ConstantSInt *CS = cast<ConstantSInt>(C);
|
|
|
|
|
|
|
|
// Calculate 0111111111..11111
|
|
|
|
unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
|
|
|
|
int64_t Val = INT64_MAX; // All ones
|
|
|
|
Val >>= 64-TypeBits; // Shift out unwanted 1 bits...
|
|
|
|
return CS->getValue() == Val-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// isMinValuePlusOne - return true if this is Min+1
|
2002-08-12 21:17:25 +00:00
|
|
|
static bool isMinValuePlusOne(const ConstantInt *C) {
|
2002-08-09 23:47:40 +00:00
|
|
|
if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(C))
|
|
|
|
return CU->getValue() == 1;
|
|
|
|
|
|
|
|
const ConstantSInt *CS = cast<ConstantSInt>(C);
|
|
|
|
|
|
|
|
// Calculate 1111111111000000000000
|
|
|
|
unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
|
|
|
|
int64_t Val = -1; // All ones
|
|
|
|
Val <<= TypeBits-1; // Shift over to the right spot
|
|
|
|
return CS->getValue() == Val+1;
|
2002-05-06 16:14:14 +00:00
|
|
|
}
|
|
|
|
|
2004-06-09 07:59:58 +00:00
|
|
|
// isOneBitSet - Return true if there is exactly one bit set in the specified
|
|
|
|
// constant.
|
|
|
|
static bool isOneBitSet(const ConstantInt *CI) {
|
|
|
|
uint64_t V = CI->getRawValue();
|
|
|
|
return V && (V & (V-1)) == 0;
|
|
|
|
}
|
|
|
|
|
2004-09-23 21:46:38 +00:00
|
|
|
#if 0 // Currently unused
|
|
|
|
// isLowOnes - Return true if the constant is of the form 0+1+.
|
|
|
|
static bool isLowOnes(const ConstantInt *CI) {
|
|
|
|
uint64_t V = CI->getRawValue();
|
|
|
|
|
|
|
|
// There won't be bits set in parts that the type doesn't contain.
|
|
|
|
V &= ConstantInt::getAllOnesValue(CI->getType())->getRawValue();
|
|
|
|
|
|
|
|
uint64_t U = V+1; // If it is low ones, this should be a power of two.
|
|
|
|
return U && V && (U & V) == 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// isHighOnes - Return true if the constant is of the form 1+0+.
|
|
|
|
// This is the same as lowones(~X).
|
|
|
|
static bool isHighOnes(const ConstantInt *CI) {
|
|
|
|
uint64_t V = ~CI->getRawValue();
|
|
|
|
|
|
|
|
// There won't be bits set in parts that the type doesn't contain.
|
|
|
|
V &= ConstantInt::getAllOnesValue(CI->getType())->getRawValue();
|
|
|
|
|
|
|
|
uint64_t U = V+1; // If it is low ones, this should be a power of two.
|
|
|
|
return U && V && (U & V) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-08-13 20:16:26 +00:00
|
|
|
/// getSetCondCode - Encode a setcc opcode into a three bit mask. These bits
|
|
|
|
/// are carefully arranged to allow folding of expressions such as:
|
|
|
|
///
|
|
|
|
/// (A < B) | (A > B) --> (A != B)
|
|
|
|
///
|
|
|
|
/// Bit value '4' represents that the comparison is true if A > B, bit value '2'
|
|
|
|
/// represents that the comparison is true if A == B, and bit value '1' is true
|
|
|
|
/// if A < B.
|
|
|
|
///
|
|
|
|
static unsigned getSetCondCode(const SetCondInst *SCI) {
|
|
|
|
switch (SCI->getOpcode()) {
|
|
|
|
// False -> 0
|
|
|
|
case Instruction::SetGT: return 1;
|
|
|
|
case Instruction::SetEQ: return 2;
|
|
|
|
case Instruction::SetGE: return 3;
|
|
|
|
case Instruction::SetLT: return 4;
|
|
|
|
case Instruction::SetNE: return 5;
|
|
|
|
case Instruction::SetLE: return 6;
|
|
|
|
// True -> 7
|
|
|
|
default:
|
|
|
|
assert(0 && "Invalid SetCC opcode!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// getSetCCValue - This is the complement of getSetCondCode, which turns an
|
|
|
|
/// opcode and two operands into either a constant true or false, or a brand new
|
|
|
|
/// SetCC instruction.
|
|
|
|
static Value *getSetCCValue(unsigned Opcode, Value *LHS, Value *RHS) {
|
|
|
|
switch (Opcode) {
|
|
|
|
case 0: return ConstantBool::False;
|
|
|
|
case 1: return new SetCondInst(Instruction::SetGT, LHS, RHS);
|
|
|
|
case 2: return new SetCondInst(Instruction::SetEQ, LHS, RHS);
|
|
|
|
case 3: return new SetCondInst(Instruction::SetGE, LHS, RHS);
|
|
|
|
case 4: return new SetCondInst(Instruction::SetLT, LHS, RHS);
|
|
|
|
case 5: return new SetCondInst(Instruction::SetNE, LHS, RHS);
|
|
|
|
case 6: return new SetCondInst(Instruction::SetLE, LHS, RHS);
|
|
|
|
case 7: return ConstantBool::True;
|
|
|
|
default: assert(0 && "Illegal SetCCCode!"); return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FoldSetCCLogical - Implements (setcc1 A, B) & (setcc2 A, B) --> (setcc3 A, B)
|
|
|
|
struct FoldSetCCLogical {
|
|
|
|
InstCombiner &IC;
|
|
|
|
Value *LHS, *RHS;
|
|
|
|
FoldSetCCLogical(InstCombiner &ic, SetCondInst *SCI)
|
|
|
|
: IC(ic), LHS(SCI->getOperand(0)), RHS(SCI->getOperand(1)) {}
|
|
|
|
bool shouldApply(Value *V) const {
|
|
|
|
if (SetCondInst *SCI = dyn_cast<SetCondInst>(V))
|
|
|
|
return (SCI->getOperand(0) == LHS && SCI->getOperand(1) == RHS ||
|
|
|
|
SCI->getOperand(0) == RHS && SCI->getOperand(1) == LHS);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Instruction *apply(BinaryOperator &Log) const {
|
|
|
|
SetCondInst *SCI = cast<SetCondInst>(Log.getOperand(0));
|
|
|
|
if (SCI->getOperand(0) != LHS) {
|
|
|
|
assert(SCI->getOperand(1) == LHS);
|
|
|
|
SCI->swapOperands(); // Swap the LHS and RHS of the SetCC
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned LHSCode = getSetCondCode(SCI);
|
|
|
|
unsigned RHSCode = getSetCondCode(cast<SetCondInst>(Log.getOperand(1)));
|
|
|
|
unsigned Code;
|
|
|
|
switch (Log.getOpcode()) {
|
|
|
|
case Instruction::And: Code = LHSCode & RHSCode; break;
|
|
|
|
case Instruction::Or: Code = LHSCode | RHSCode; break;
|
|
|
|
case Instruction::Xor: Code = LHSCode ^ RHSCode; break;
|
2003-09-22 20:33:34 +00:00
|
|
|
default: assert(0 && "Illegal logical opcode!"); return 0;
|
2003-08-13 20:16:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Value *RV = getSetCCValue(Code, LHS, RHS);
|
|
|
|
if (Instruction *I = dyn_cast<Instruction>(RV))
|
|
|
|
return I;
|
|
|
|
// Otherwise, it's a constant boolean value...
|
|
|
|
return IC.ReplaceInstUsesWith(Log, RV);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2003-09-19 17:17:26 +00:00
|
|
|
// OptAndOp - This handles expressions of the form ((val OP C1) & C2). Where
|
|
|
|
// the Op parameter is 'OP', OpRHS is 'C1', and AndRHS is 'C2'. Op is
|
|
|
|
// guaranteed to be either a shift instruction or a binary operator.
|
|
|
|
Instruction *InstCombiner::OptAndOp(Instruction *Op,
|
|
|
|
ConstantIntegral *OpRHS,
|
|
|
|
ConstantIntegral *AndRHS,
|
|
|
|
BinaryOperator &TheAnd) {
|
|
|
|
Value *X = Op->getOperand(0);
|
2004-01-12 19:47:05 +00:00
|
|
|
Constant *Together = 0;
|
|
|
|
if (!isa<ShiftInst>(Op))
|
2004-06-10 02:07:29 +00:00
|
|
|
Together = ConstantExpr::getAnd(AndRHS, OpRHS);
|
2004-01-12 19:35:11 +00:00
|
|
|
|
2003-09-19 17:17:26 +00:00
|
|
|
switch (Op->getOpcode()) {
|
|
|
|
case Instruction::Xor:
|
2004-01-12 19:35:11 +00:00
|
|
|
if (Together->isNullValue()) {
|
2003-09-19 17:17:26 +00:00
|
|
|
// (X ^ C1) & C2 --> (X & C2) iff (C1&C2) == 0
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(X, AndRHS);
|
2003-10-15 16:48:29 +00:00
|
|
|
} else if (Op->hasOneUse()) {
|
2003-09-19 17:17:26 +00:00
|
|
|
// (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
|
|
|
|
std::string OpName = Op->getName(); Op->setName("");
|
2004-06-10 02:07:29 +00:00
|
|
|
Instruction *And = BinaryOperator::createAnd(X, AndRHS, OpName);
|
2003-09-19 17:17:26 +00:00
|
|
|
InsertNewInstBefore(And, TheAnd);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createXor(And, Together);
|
2003-09-19 17:17:26 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Instruction::Or:
|
|
|
|
// (X | C1) & C2 --> X & C2 iff C1 & C1 == 0
|
2004-01-12 19:35:11 +00:00
|
|
|
if (Together->isNullValue())
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(X, AndRHS);
|
2003-09-19 17:17:26 +00:00
|
|
|
else {
|
|
|
|
if (Together == AndRHS) // (X | C) & C --> C
|
|
|
|
return ReplaceInstUsesWith(TheAnd, AndRHS);
|
|
|
|
|
2003-10-15 16:48:29 +00:00
|
|
|
if (Op->hasOneUse() && Together != OpRHS) {
|
2003-09-19 17:17:26 +00:00
|
|
|
// (X | C1) & C2 --> (X | (C1&C2)) & C2
|
|
|
|
std::string Op0Name = Op->getName(); Op->setName("");
|
2004-06-10 02:07:29 +00:00
|
|
|
Instruction *Or = BinaryOperator::createOr(X, Together, Op0Name);
|
2003-09-19 17:17:26 +00:00
|
|
|
InsertNewInstBefore(Or, TheAnd);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(Or, AndRHS);
|
2003-09-19 17:17:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Instruction::Add:
|
2003-10-15 16:48:29 +00:00
|
|
|
if (Op->hasOneUse()) {
|
2003-09-19 17:17:26 +00:00
|
|
|
// Adding a one to a single bit bit-field should be turned into an XOR
|
|
|
|
// of the bit. First thing to check is to see if this AND is with a
|
|
|
|
// single bit constant.
|
2004-06-09 07:59:58 +00:00
|
|
|
uint64_t AndRHSV = cast<ConstantInt>(AndRHS)->getRawValue();
|
2003-09-19 17:17:26 +00:00
|
|
|
|
|
|
|
// Clear bits that are not part of the constant.
|
|
|
|
AndRHSV &= (1ULL << AndRHS->getType()->getPrimitiveSize()*8)-1;
|
|
|
|
|
|
|
|
// If there is only one bit set...
|
2004-06-09 07:59:58 +00:00
|
|
|
if (isOneBitSet(cast<ConstantInt>(AndRHS))) {
|
2003-09-19 17:17:26 +00:00
|
|
|
// Ok, at this point, we know that we are masking the result of the
|
|
|
|
// ADD down to exactly one bit. If the constant we are adding has
|
|
|
|
// no bits set below this bit, then we can eliminate the ADD.
|
2004-06-09 07:59:58 +00:00
|
|
|
uint64_t AddRHS = cast<ConstantInt>(OpRHS)->getRawValue();
|
2003-09-19 17:17:26 +00:00
|
|
|
|
|
|
|
// Check to see if any bits below the one bit set in AndRHSV are set.
|
|
|
|
if ((AddRHS & (AndRHSV-1)) == 0) {
|
|
|
|
// If not, the only thing that can effect the output of the AND is
|
|
|
|
// the bit specified by AndRHSV. If that bit is set, the effect of
|
|
|
|
// the XOR is to toggle the bit. If it is clear, then the ADD has
|
|
|
|
// no effect.
|
|
|
|
if ((AddRHS & AndRHSV) == 0) { // Bit is not set, noop
|
|
|
|
TheAnd.setOperand(0, X);
|
|
|
|
return &TheAnd;
|
|
|
|
} else {
|
|
|
|
std::string Name = Op->getName(); Op->setName("");
|
|
|
|
// Pull the XOR out of the AND.
|
2004-06-10 02:07:29 +00:00
|
|
|
Instruction *NewAnd = BinaryOperator::createAnd(X, AndRHS, Name);
|
2003-09-19 17:17:26 +00:00
|
|
|
InsertNewInstBefore(NewAnd, TheAnd);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createXor(NewAnd, AndRHS);
|
2003-09-19 17:17:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2003-09-19 19:05:02 +00:00
|
|
|
|
|
|
|
case Instruction::Shl: {
|
|
|
|
// We know that the AND will not produce any of the bits shifted in, so if
|
|
|
|
// the anded constant includes them, clear them now!
|
|
|
|
//
|
|
|
|
Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
|
2004-09-24 15:21:34 +00:00
|
|
|
Constant *ShlMask = ConstantExpr::getShl(AllOne, OpRHS);
|
|
|
|
Constant *CI = ConstantExpr::getAnd(AndRHS, ShlMask);
|
|
|
|
|
|
|
|
if (CI == ShlMask) { // Masking out bits that the shift already masks
|
|
|
|
return ReplaceInstUsesWith(TheAnd, Op); // No need for the and.
|
|
|
|
} else if (CI != AndRHS) { // Reducing bits set in and.
|
2003-09-19 19:05:02 +00:00
|
|
|
TheAnd.setOperand(1, CI);
|
|
|
|
return &TheAnd;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Instruction::Shr:
|
|
|
|
// We know that the AND will not produce any of the bits shifted in, so if
|
|
|
|
// the anded constant includes them, clear them now! This only applies to
|
|
|
|
// unsigned shifts, because a signed shr may bring in set bits!
|
|
|
|
//
|
|
|
|
if (AndRHS->getType()->isUnsigned()) {
|
|
|
|
Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
|
2004-09-24 15:21:34 +00:00
|
|
|
Constant *ShrMask = ConstantExpr::getShr(AllOne, OpRHS);
|
|
|
|
Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask);
|
|
|
|
|
|
|
|
if (CI == ShrMask) { // Masking out bits that the shift already masks.
|
|
|
|
return ReplaceInstUsesWith(TheAnd, Op);
|
|
|
|
} else if (CI != AndRHS) {
|
|
|
|
TheAnd.setOperand(1, CI); // Reduce bits set in and cst.
|
2003-09-19 19:05:02 +00:00
|
|
|
return &TheAnd;
|
|
|
|
}
|
2004-09-24 15:21:34 +00:00
|
|
|
} else { // Signed shr.
|
|
|
|
// See if this is shifting in some sign extension, then masking it out
|
|
|
|
// with an and.
|
|
|
|
if (Op->hasOneUse()) {
|
|
|
|
Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
|
|
|
|
Constant *ShrMask = ConstantExpr::getUShr(AllOne, OpRHS);
|
|
|
|
Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask);
|
2004-10-22 04:53:16 +00:00
|
|
|
if (CI == AndRHS) { // Masking out bits shifted in.
|
2004-09-24 15:21:34 +00:00
|
|
|
// Make the argument unsigned.
|
|
|
|
Value *ShVal = Op->getOperand(0);
|
|
|
|
ShVal = InsertCastBefore(ShVal,
|
|
|
|
ShVal->getType()->getUnsignedVersion(),
|
|
|
|
TheAnd);
|
|
|
|
ShVal = InsertNewInstBefore(new ShiftInst(Instruction::Shr, ShVal,
|
|
|
|
OpRHS, Op->getName()),
|
|
|
|
TheAnd);
|
2004-10-27 05:57:15 +00:00
|
|
|
Value *AndRHS2 = ConstantExpr::getCast(AndRHS, ShVal->getType());
|
|
|
|
ShVal = InsertNewInstBefore(BinaryOperator::createAnd(ShVal, AndRHS2,
|
|
|
|
TheAnd.getName()),
|
|
|
|
TheAnd);
|
2004-09-24 15:21:34 +00:00
|
|
|
return new CastInst(ShVal, Op->getType());
|
|
|
|
}
|
|
|
|
}
|
2003-09-19 19:05:02 +00:00
|
|
|
}
|
|
|
|
break;
|
2003-09-19 17:17:26 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2004-09-29 17:40:11 +00:00
|
|
|
/// InsertRangeTest - Emit a computation of: (V >= Lo && V < Hi) if Inside is
|
|
|
|
/// true, otherwise (V < Lo || V >= Hi). In pratice, we emit the more efficient
|
|
|
|
/// (V-Lo) <u Hi-Lo. This method expects that Lo <= Hi. IB is the location to
|
|
|
|
/// insert new instructions.
|
|
|
|
Instruction *InstCombiner::InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
|
|
|
|
bool Inside, Instruction &IB) {
|
|
|
|
assert(cast<ConstantBool>(ConstantExpr::getSetLE(Lo, Hi))->getValue() &&
|
|
|
|
"Lo is not <= Hi in range emission code!");
|
|
|
|
if (Inside) {
|
|
|
|
if (Lo == Hi) // Trivially false.
|
|
|
|
return new SetCondInst(Instruction::SetNE, V, V);
|
|
|
|
if (cast<ConstantIntegral>(Lo)->isMinValue())
|
|
|
|
return new SetCondInst(Instruction::SetLT, V, Hi);
|
|
|
|
|
|
|
|
Constant *AddCST = ConstantExpr::getNeg(Lo);
|
|
|
|
Instruction *Add = BinaryOperator::createAdd(V, AddCST,V->getName()+".off");
|
|
|
|
InsertNewInstBefore(Add, IB);
|
|
|
|
// Convert to unsigned for the comparison.
|
|
|
|
const Type *UnsType = Add->getType()->getUnsignedVersion();
|
|
|
|
Value *OffsetVal = InsertCastBefore(Add, UnsType, IB);
|
|
|
|
AddCST = ConstantExpr::getAdd(AddCST, Hi);
|
|
|
|
AddCST = ConstantExpr::getCast(AddCST, UnsType);
|
|
|
|
return new SetCondInst(Instruction::SetLT, OffsetVal, AddCST);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Lo == Hi) // Trivially true.
|
|
|
|
return new SetCondInst(Instruction::SetEQ, V, V);
|
|
|
|
|
|
|
|
Hi = SubOne(cast<ConstantInt>(Hi));
|
|
|
|
if (cast<ConstantIntegral>(Lo)->isMinValue()) // V < 0 || V >= Hi ->'V > Hi-1'
|
|
|
|
return new SetCondInst(Instruction::SetGT, V, Hi);
|
|
|
|
|
|
|
|
// Emit X-Lo > Hi-Lo-1
|
|
|
|
Constant *AddCST = ConstantExpr::getNeg(Lo);
|
|
|
|
Instruction *Add = BinaryOperator::createAdd(V, AddCST, V->getName()+".off");
|
|
|
|
InsertNewInstBefore(Add, IB);
|
|
|
|
// Convert to unsigned for the comparison.
|
|
|
|
const Type *UnsType = Add->getType()->getUnsignedVersion();
|
|
|
|
Value *OffsetVal = InsertCastBefore(Add, UnsType, IB);
|
|
|
|
AddCST = ConstantExpr::getAdd(AddCST, Hi);
|
|
|
|
AddCST = ConstantExpr::getCast(AddCST, UnsType);
|
|
|
|
return new SetCondInst(Instruction::SetGT, OffsetVal, AddCST);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
2003-03-10 21:43:22 +00:00
|
|
|
bool Changed = SimplifyCommutative(I);
|
2002-06-25 16:13:24 +00:00
|
|
|
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(Op1)) // X & undef -> 0
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
|
|
|
2002-05-06 16:14:14 +00:00
|
|
|
// and X, X = X and X, 0 == 0
|
2002-08-12 21:17:25 +00:00
|
|
|
if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType()))
|
|
|
|
return ReplaceInstUsesWith(I, Op1);
|
2002-05-06 16:14:14 +00:00
|
|
|
|
|
|
|
// and X, -1 == X
|
2003-07-23 17:57:01 +00:00
|
|
|
if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
|
2002-08-12 21:17:25 +00:00
|
|
|
if (RHS->isAllOnesValue())
|
|
|
|
return ReplaceInstUsesWith(I, Op0);
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2003-09-19 17:17:26 +00:00
|
|
|
// Optimize a variety of ((val OP C1) & C2) combinations...
|
|
|
|
if (isa<BinaryOperator>(Op0) || isa<ShiftInst>(Op0)) {
|
|
|
|
Instruction *Op0I = cast<Instruction>(Op0);
|
2003-07-23 19:36:21 +00:00
|
|
|
Value *X = Op0I->getOperand(0);
|
2003-07-23 19:25:52 +00:00
|
|
|
if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
|
2003-09-19 17:17:26 +00:00
|
|
|
if (Instruction *Res = OptAndOp(Op0I, Op0CI, RHS, I))
|
|
|
|
return Res;
|
2003-07-23 19:36:21 +00:00
|
|
|
}
|
2004-04-09 19:05:30 +00:00
|
|
|
|
|
|
|
// Try to fold constant and into select arguments.
|
|
|
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
|
|
|
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
|
|
|
|
return R;
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
if (isa<PHINode>(Op0))
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
2003-07-23 17:57:01 +00:00
|
|
|
}
|
|
|
|
|
2003-03-10 23:06:50 +00:00
|
|
|
Value *Op0NotVal = dyn_castNotVal(Op0);
|
|
|
|
Value *Op1NotVal = dyn_castNotVal(Op1);
|
2003-02-18 19:28:33 +00:00
|
|
|
|
2004-06-18 06:07:51 +00:00
|
|
|
if (Op0NotVal == Op1 || Op1NotVal == Op0) // A & ~A == ~A & A == 0
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
|
|
|
2004-07-30 12:50:08 +00:00
|
|
|
// (~A & ~B) == (~(A | B)) - De Morgan's Law
|
2003-03-10 23:06:50 +00:00
|
|
|
if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) {
|
2004-06-10 02:07:29 +00:00
|
|
|
Instruction *Or = BinaryOperator::createOr(Op0NotVal, Op1NotVal,
|
|
|
|
I.getName()+".demorgan");
|
2003-07-23 17:57:01 +00:00
|
|
|
InsertNewInstBefore(Or, I);
|
2003-02-18 19:28:33 +00:00
|
|
|
return BinaryOperator::createNot(Or);
|
|
|
|
}
|
|
|
|
|
Fold (and (setcc X, C1), (setcc X, C2))
This is important for several reasons:
1. Benchmarks have lots of code that looks like this (perlbmk in particular):
%tmp.2.i = setne int %tmp.0.i, 128 ; <bool> [#uses=1]
%tmp.6343 = seteq int %tmp.0.i, 1 ; <bool> [#uses=1]
%tmp.63 = and bool %tmp.2.i, %tmp.6343 ; <bool> [#uses=1]
we now fold away the setne, a clear improvement.
2. In the more important cases, such as (X >= 10) & (X < 20), we now produce
smaller code: (X-10) < 10.
3. Perhaps the nicest effect of this patch is that it really helps out the
code generators. In particular, for a 'range test' like the above,
instead of generating this on X86 (the difference on PPC is even more
pronounced):
cmp %EAX, 50
setge %CL
cmp %EAX, 100
setl %AL
and %CL, %AL
cmp %CL, 0
we now generate this:
add %EAX, -50
cmp %EAX, 50
Furthermore, this causes setcc's to be folded into branches more often.
These combinations trigger dozens of times in the spec benchmarks, particularly
in 176.gcc, 186.crafty, 253.perlbmk, 254.gap, & 099.go.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16559 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-28 21:48:02 +00:00
|
|
|
if (SetCondInst *RHS = dyn_cast<SetCondInst>(Op1)) {
|
|
|
|
// (setcc1 A, B) & (setcc2 A, B) --> (setcc3 A, B)
|
2003-08-13 20:16:26 +00:00
|
|
|
if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
|
|
|
|
return R;
|
|
|
|
|
Fold (and (setcc X, C1), (setcc X, C2))
This is important for several reasons:
1. Benchmarks have lots of code that looks like this (perlbmk in particular):
%tmp.2.i = setne int %tmp.0.i, 128 ; <bool> [#uses=1]
%tmp.6343 = seteq int %tmp.0.i, 1 ; <bool> [#uses=1]
%tmp.63 = and bool %tmp.2.i, %tmp.6343 ; <bool> [#uses=1]
we now fold away the setne, a clear improvement.
2. In the more important cases, such as (X >= 10) & (X < 20), we now produce
smaller code: (X-10) < 10.
3. Perhaps the nicest effect of this patch is that it really helps out the
code generators. In particular, for a 'range test' like the above,
instead of generating this on X86 (the difference on PPC is even more
pronounced):
cmp %EAX, 50
setge %CL
cmp %EAX, 100
setl %AL
and %CL, %AL
cmp %CL, 0
we now generate this:
add %EAX, -50
cmp %EAX, 50
Furthermore, this causes setcc's to be folded into branches more often.
These combinations trigger dozens of times in the spec benchmarks, particularly
in 176.gcc, 186.crafty, 253.perlbmk, 254.gap, & 099.go.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16559 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-28 21:48:02 +00:00
|
|
|
Value *LHSVal, *RHSVal;
|
|
|
|
ConstantInt *LHSCst, *RHSCst;
|
|
|
|
Instruction::BinaryOps LHSCC, RHSCC;
|
|
|
|
if (match(Op0, m_SetCond(LHSCC, m_Value(LHSVal), m_ConstantInt(LHSCst))))
|
|
|
|
if (match(RHS, m_SetCond(RHSCC, m_Value(RHSVal), m_ConstantInt(RHSCst))))
|
|
|
|
if (LHSVal == RHSVal && // Found (X setcc C1) & (X setcc C2)
|
|
|
|
// Set[GL]E X, CST is folded to Set[GL]T elsewhere.
|
|
|
|
LHSCC != Instruction::SetGE && LHSCC != Instruction::SetLE &&
|
|
|
|
RHSCC != Instruction::SetGE && RHSCC != Instruction::SetLE) {
|
|
|
|
// Ensure that the larger constant is on the RHS.
|
|
|
|
Constant *Cmp = ConstantExpr::getSetGT(LHSCst, RHSCst);
|
|
|
|
SetCondInst *LHS = cast<SetCondInst>(Op0);
|
|
|
|
if (cast<ConstantBool>(Cmp)->getValue()) {
|
|
|
|
std::swap(LHS, RHS);
|
|
|
|
std::swap(LHSCst, RHSCst);
|
|
|
|
std::swap(LHSCC, RHSCC);
|
|
|
|
}
|
|
|
|
|
|
|
|
// At this point, we know we have have two setcc instructions
|
|
|
|
// comparing a value against two constants and and'ing the result
|
|
|
|
// together. Because of the above check, we know that we only have
|
|
|
|
// SetEQ, SetNE, SetLT, and SetGT here. We also know (from the
|
|
|
|
// FoldSetCCLogical check above), that the two constants are not
|
|
|
|
// equal.
|
|
|
|
assert(LHSCst != RHSCst && "Compares not folded above?");
|
|
|
|
|
|
|
|
switch (LHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetEQ:
|
|
|
|
switch (RHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetEQ: // (X == 13 & X == 15) -> false
|
|
|
|
case Instruction::SetGT: // (X == 13 & X > 15) -> false
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
case Instruction::SetNE: // (X == 13 & X != 15) -> X == 13
|
|
|
|
case Instruction::SetLT: // (X == 13 & X < 15) -> X == 13
|
|
|
|
return ReplaceInstUsesWith(I, LHS);
|
|
|
|
}
|
|
|
|
case Instruction::SetNE:
|
|
|
|
switch (RHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetLT:
|
|
|
|
if (LHSCst == SubOne(RHSCst)) // (X != 13 & X < 14) -> X < 13
|
|
|
|
return new SetCondInst(Instruction::SetLT, LHSVal, LHSCst);
|
|
|
|
break; // (X != 13 & X < 15) -> no change
|
|
|
|
case Instruction::SetEQ: // (X != 13 & X == 15) -> X == 15
|
|
|
|
case Instruction::SetGT: // (X != 13 & X > 15) -> X > 15
|
|
|
|
return ReplaceInstUsesWith(I, RHS);
|
|
|
|
case Instruction::SetNE:
|
|
|
|
if (LHSCst == SubOne(RHSCst)) {// (X != 13 & X != 14) -> X-13 >u 1
|
|
|
|
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
|
|
|
|
Instruction *Add = BinaryOperator::createAdd(LHSVal, AddCST,
|
|
|
|
LHSVal->getName()+".off");
|
|
|
|
InsertNewInstBefore(Add, I);
|
|
|
|
const Type *UnsType = Add->getType()->getUnsignedVersion();
|
|
|
|
Value *OffsetVal = InsertCastBefore(Add, UnsType, I);
|
|
|
|
AddCST = ConstantExpr::getSub(RHSCst, LHSCst);
|
|
|
|
AddCST = ConstantExpr::getCast(AddCST, UnsType);
|
|
|
|
return new SetCondInst(Instruction::SetGT, OffsetVal, AddCST);
|
|
|
|
}
|
|
|
|
break; // (X != 13 & X != 15) -> no change
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Instruction::SetLT:
|
|
|
|
switch (RHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetEQ: // (X < 13 & X == 15) -> false
|
|
|
|
case Instruction::SetGT: // (X < 13 & X > 15) -> false
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
case Instruction::SetNE: // (X < 13 & X != 15) -> X < 13
|
|
|
|
case Instruction::SetLT: // (X < 13 & X < 15) -> X < 13
|
|
|
|
return ReplaceInstUsesWith(I, LHS);
|
|
|
|
}
|
|
|
|
case Instruction::SetGT:
|
|
|
|
switch (RHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetEQ: // (X > 13 & X == 15) -> X > 13
|
|
|
|
return ReplaceInstUsesWith(I, LHS);
|
|
|
|
case Instruction::SetGT: // (X > 13 & X > 15) -> X > 15
|
|
|
|
return ReplaceInstUsesWith(I, RHS);
|
|
|
|
case Instruction::SetNE:
|
|
|
|
if (RHSCst == AddOne(LHSCst)) // (X > 13 & X != 14) -> X > 14
|
|
|
|
return new SetCondInst(Instruction::SetGT, LHSVal, RHSCst);
|
|
|
|
break; // (X > 13 & X != 15) -> no change
|
2004-09-29 17:40:11 +00:00
|
|
|
case Instruction::SetLT: // (X > 13 & X < 15) -> (X-14) <u 1
|
|
|
|
return InsertRangeTest(LHSVal, AddOne(LHSCst), RHSCst, true, I);
|
Fold (and (setcc X, C1), (setcc X, C2))
This is important for several reasons:
1. Benchmarks have lots of code that looks like this (perlbmk in particular):
%tmp.2.i = setne int %tmp.0.i, 128 ; <bool> [#uses=1]
%tmp.6343 = seteq int %tmp.0.i, 1 ; <bool> [#uses=1]
%tmp.63 = and bool %tmp.2.i, %tmp.6343 ; <bool> [#uses=1]
we now fold away the setne, a clear improvement.
2. In the more important cases, such as (X >= 10) & (X < 20), we now produce
smaller code: (X-10) < 10.
3. Perhaps the nicest effect of this patch is that it really helps out the
code generators. In particular, for a 'range test' like the above,
instead of generating this on X86 (the difference on PPC is even more
pronounced):
cmp %EAX, 50
setge %CL
cmp %EAX, 100
setl %AL
and %CL, %AL
cmp %CL, 0
we now generate this:
add %EAX, -50
cmp %EAX, 50
Furthermore, this causes setcc's to be folded into branches more often.
These combinations trigger dozens of times in the spec benchmarks, particularly
in 176.gcc, 186.crafty, 253.perlbmk, 254.gap, & 099.go.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16559 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-28 21:48:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
return Changed ? &I : 0;
|
2002-05-06 16:14:14 +00:00
|
|
|
}
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
2003-03-10 21:43:22 +00:00
|
|
|
bool Changed = SimplifyCommutative(I);
|
2002-06-25 16:13:24 +00:00
|
|
|
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(Op1))
|
|
|
|
return ReplaceInstUsesWith(I, // X | undef -> -1
|
|
|
|
ConstantIntegral::getAllOnesValue(I.getType()));
|
|
|
|
|
2002-05-06 16:14:14 +00:00
|
|
|
// or X, X = X or X, 0 == X
|
2002-08-12 21:17:25 +00:00
|
|
|
if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType()))
|
|
|
|
return ReplaceInstUsesWith(I, Op0);
|
2002-05-06 16:14:14 +00:00
|
|
|
|
|
|
|
// or X, -1 == -1
|
2003-07-23 18:29:44 +00:00
|
|
|
if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
|
2002-08-12 21:17:25 +00:00
|
|
|
if (RHS->isAllOnesValue())
|
|
|
|
return ReplaceInstUsesWith(I, Op1);
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2004-07-30 07:50:03 +00:00
|
|
|
ConstantInt *C1; Value *X;
|
|
|
|
// (X & C1) | C2 --> (X | C2) & (C1|C2)
|
|
|
|
if (match(Op0, m_And(m_Value(X), m_ConstantInt(C1))) && isOnlyUse(Op0)) {
|
|
|
|
std::string Op0Name = Op0->getName(); Op0->setName("");
|
|
|
|
Instruction *Or = BinaryOperator::createOr(X, RHS, Op0Name);
|
|
|
|
InsertNewInstBefore(Or, I);
|
|
|
|
return BinaryOperator::createAnd(Or, ConstantExpr::getOr(RHS, C1));
|
|
|
|
}
|
2003-07-23 18:29:44 +00:00
|
|
|
|
2004-07-30 07:50:03 +00:00
|
|
|
// (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
|
|
|
|
if (match(Op0, m_Xor(m_Value(X), m_ConstantInt(C1))) && isOnlyUse(Op0)) {
|
|
|
|
std::string Op0Name = Op0->getName(); Op0->setName("");
|
|
|
|
Instruction *Or = BinaryOperator::createOr(X, RHS, Op0Name);
|
|
|
|
InsertNewInstBefore(Or, I);
|
|
|
|
return BinaryOperator::createXor(Or,
|
|
|
|
ConstantExpr::getAnd(C1, ConstantExpr::getNot(RHS)));
|
2003-07-23 18:29:44 +00:00
|
|
|
}
|
2004-04-09 19:05:30 +00:00
|
|
|
|
|
|
|
// Try to fold constant and into select arguments.
|
|
|
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
|
|
|
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
|
|
|
|
return R;
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
if (isa<PHINode>(Op0))
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
2003-07-23 18:29:44 +00:00
|
|
|
}
|
|
|
|
|
2003-08-12 19:11:07 +00:00
|
|
|
// (A & C1)|(A & C2) == A & (C1|C2)
|
2004-07-30 07:50:03 +00:00
|
|
|
Value *A, *B; ConstantInt *C1, *C2;
|
|
|
|
if (match(Op0, m_And(m_Value(A), m_ConstantInt(C1))) &&
|
|
|
|
match(Op1, m_And(m_Value(B), m_ConstantInt(C2))) && A == B)
|
|
|
|
return BinaryOperator::createAnd(A, ConstantExpr::getOr(C1, C2));
|
|
|
|
|
|
|
|
if (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1
|
|
|
|
if (A == Op1) // ~A | A == -1
|
|
|
|
return ReplaceInstUsesWith(I,
|
|
|
|
ConstantIntegral::getAllOnesValue(I.getType()));
|
|
|
|
} else {
|
|
|
|
A = 0;
|
|
|
|
}
|
2003-02-18 19:28:33 +00:00
|
|
|
|
2004-07-30 07:50:03 +00:00
|
|
|
if (match(Op1, m_Not(m_Value(B)))) { // Op0 | ~B
|
|
|
|
if (Op0 == B)
|
|
|
|
return ReplaceInstUsesWith(I,
|
|
|
|
ConstantIntegral::getAllOnesValue(I.getType()));
|
2003-03-10 23:13:59 +00:00
|
|
|
|
2004-07-30 12:50:08 +00:00
|
|
|
// (~A | ~B) == (~(A & B)) - De Morgan's Law
|
2004-07-30 07:50:03 +00:00
|
|
|
if (A && isOnlyUse(Op0) && isOnlyUse(Op1)) {
|
|
|
|
Value *And = InsertNewInstBefore(BinaryOperator::createAnd(A, B,
|
|
|
|
I.getName()+".demorgan"), I);
|
|
|
|
return BinaryOperator::createNot(And);
|
|
|
|
}
|
2003-03-10 23:13:59 +00:00
|
|
|
}
|
2003-02-18 19:28:33 +00:00
|
|
|
|
2003-08-13 20:16:26 +00:00
|
|
|
// (setcc1 A, B) | (setcc2 A, B) --> (setcc3 A, B)
|
2004-09-28 22:33:08 +00:00
|
|
|
if (SetCondInst *RHS = dyn_cast<SetCondInst>(I.getOperand(1))) {
|
2003-08-13 20:16:26 +00:00
|
|
|
if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
|
|
|
|
return R;
|
|
|
|
|
2004-09-28 22:33:08 +00:00
|
|
|
Value *LHSVal, *RHSVal;
|
|
|
|
ConstantInt *LHSCst, *RHSCst;
|
|
|
|
Instruction::BinaryOps LHSCC, RHSCC;
|
|
|
|
if (match(Op0, m_SetCond(LHSCC, m_Value(LHSVal), m_ConstantInt(LHSCst))))
|
|
|
|
if (match(RHS, m_SetCond(RHSCC, m_Value(RHSVal), m_ConstantInt(RHSCst))))
|
|
|
|
if (LHSVal == RHSVal && // Found (X setcc C1) | (X setcc C2)
|
|
|
|
// Set[GL]E X, CST is folded to Set[GL]T elsewhere.
|
|
|
|
LHSCC != Instruction::SetGE && LHSCC != Instruction::SetLE &&
|
|
|
|
RHSCC != Instruction::SetGE && RHSCC != Instruction::SetLE) {
|
|
|
|
// Ensure that the larger constant is on the RHS.
|
|
|
|
Constant *Cmp = ConstantExpr::getSetGT(LHSCst, RHSCst);
|
|
|
|
SetCondInst *LHS = cast<SetCondInst>(Op0);
|
|
|
|
if (cast<ConstantBool>(Cmp)->getValue()) {
|
|
|
|
std::swap(LHS, RHS);
|
|
|
|
std::swap(LHSCst, RHSCst);
|
|
|
|
std::swap(LHSCC, RHSCC);
|
|
|
|
}
|
|
|
|
|
|
|
|
// At this point, we know we have have two setcc instructions
|
|
|
|
// comparing a value against two constants and or'ing the result
|
|
|
|
// together. Because of the above check, we know that we only have
|
|
|
|
// SetEQ, SetNE, SetLT, and SetGT here. We also know (from the
|
|
|
|
// FoldSetCCLogical check above), that the two constants are not
|
|
|
|
// equal.
|
|
|
|
assert(LHSCst != RHSCst && "Compares not folded above?");
|
|
|
|
|
|
|
|
switch (LHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetEQ:
|
|
|
|
switch (RHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetEQ:
|
|
|
|
if (LHSCst == SubOne(RHSCst)) {// (X == 13 | X == 14) -> X-13 <u 2
|
|
|
|
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
|
|
|
|
Instruction *Add = BinaryOperator::createAdd(LHSVal, AddCST,
|
|
|
|
LHSVal->getName()+".off");
|
|
|
|
InsertNewInstBefore(Add, I);
|
|
|
|
const Type *UnsType = Add->getType()->getUnsignedVersion();
|
|
|
|
Value *OffsetVal = InsertCastBefore(Add, UnsType, I);
|
|
|
|
AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst);
|
|
|
|
AddCST = ConstantExpr::getCast(AddCST, UnsType);
|
|
|
|
return new SetCondInst(Instruction::SetLT, OffsetVal, AddCST);
|
|
|
|
}
|
|
|
|
break; // (X == 13 | X == 15) -> no change
|
|
|
|
|
|
|
|
case Instruction::SetGT:
|
|
|
|
if (LHSCst == SubOne(RHSCst)) // (X == 13 | X > 14) -> X > 13
|
|
|
|
return new SetCondInst(Instruction::SetGT, LHSVal, LHSCst);
|
|
|
|
break; // (X == 13 | X > 15) -> no change
|
|
|
|
case Instruction::SetNE: // (X == 13 | X != 15) -> X != 15
|
|
|
|
case Instruction::SetLT: // (X == 13 | X < 15) -> X < 15
|
|
|
|
return ReplaceInstUsesWith(I, RHS);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Instruction::SetNE:
|
|
|
|
switch (RHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetLT: // (X != 13 | X < 15) -> X < 15
|
|
|
|
return ReplaceInstUsesWith(I, RHS);
|
|
|
|
case Instruction::SetEQ: // (X != 13 | X == 15) -> X != 13
|
|
|
|
case Instruction::SetGT: // (X != 13 | X > 15) -> X != 13
|
|
|
|
return ReplaceInstUsesWith(I, LHS);
|
|
|
|
case Instruction::SetNE: // (X != 13 | X != 15) -> true
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Instruction::SetLT:
|
|
|
|
switch (RHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetEQ: // (X < 13 | X == 14) -> no change
|
|
|
|
break;
|
2004-09-29 17:40:11 +00:00
|
|
|
case Instruction::SetGT: // (X < 13 | X > 15) -> (X-13) > 2
|
|
|
|
return InsertRangeTest(LHSVal, LHSCst, AddOne(RHSCst), false, I);
|
2004-09-28 22:33:08 +00:00
|
|
|
case Instruction::SetNE: // (X < 13 | X != 15) -> X != 15
|
|
|
|
case Instruction::SetLT: // (X < 13 | X < 15) -> X < 15
|
|
|
|
return ReplaceInstUsesWith(I, RHS);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Instruction::SetGT:
|
|
|
|
switch (RHSCC) {
|
|
|
|
default: assert(0 && "Unknown integer condition code!");
|
|
|
|
case Instruction::SetEQ: // (X > 13 | X == 15) -> X > 13
|
|
|
|
case Instruction::SetGT: // (X > 13 | X > 15) -> X > 13
|
|
|
|
return ReplaceInstUsesWith(I, LHS);
|
|
|
|
case Instruction::SetNE: // (X > 13 | X != 15) -> true
|
|
|
|
case Instruction::SetLT: // (X > 13 | X < 15) -> true
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-06-25 16:13:24 +00:00
|
|
|
return Changed ? &I : 0;
|
2002-05-06 16:14:14 +00:00
|
|
|
}
|
|
|
|
|
2004-02-16 01:20:27 +00:00
|
|
|
// XorSelf - Implements: X ^ X --> 0
|
|
|
|
struct XorSelf {
|
|
|
|
Value *RHS;
|
|
|
|
XorSelf(Value *rhs) : RHS(rhs) {}
|
|
|
|
bool shouldApply(Value *LHS) const { return LHS == RHS; }
|
|
|
|
Instruction *apply(BinaryOperator &Xor) const {
|
|
|
|
return &Xor;
|
|
|
|
}
|
|
|
|
};
|
2002-05-06 16:14:14 +00:00
|
|
|
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
2003-03-10 21:43:22 +00:00
|
|
|
bool Changed = SimplifyCommutative(I);
|
2002-06-25 16:13:24 +00:00
|
|
|
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(Op1))
|
|
|
|
return ReplaceInstUsesWith(I, Op1); // X ^ undef -> undef
|
|
|
|
|
2004-02-16 01:20:27 +00:00
|
|
|
// xor X, X = 0, even if X is nested in a sequence of Xor's.
|
|
|
|
if (Instruction *Result = AssociativeOpt(I, XorSelf(Op1))) {
|
|
|
|
assert(Result == &I && "AssociativeOpt didn't work?");
|
2002-08-12 21:17:25 +00:00
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
2004-02-16 01:20:27 +00:00
|
|
|
}
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2003-07-23 21:37:07 +00:00
|
|
|
if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
|
2002-08-09 23:47:40 +00:00
|
|
|
// xor X, 0 == X
|
2003-07-23 21:37:07 +00:00
|
|
|
if (RHS->isNullValue())
|
2002-08-12 21:17:25 +00:00
|
|
|
return ReplaceInstUsesWith(I, Op0);
|
2002-08-09 23:47:40 +00:00
|
|
|
|
2003-07-23 21:37:07 +00:00
|
|
|
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
|
2002-08-20 18:24:26 +00:00
|
|
|
// xor (setcc A, B), true = not (setcc A, B) = setncc A, B
|
2003-07-23 21:37:07 +00:00
|
|
|
if (SetCondInst *SCI = dyn_cast<SetCondInst>(Op0I))
|
2003-10-15 16:48:29 +00:00
|
|
|
if (RHS == ConstantBool::True && SCI->hasOneUse())
|
2002-08-20 18:24:26 +00:00
|
|
|
return new SetCondInst(SCI->getInverseCondition(),
|
|
|
|
SCI->getOperand(0), SCI->getOperand(1));
|
2003-11-04 23:50:51 +00:00
|
|
|
|
2003-11-05 01:06:05 +00:00
|
|
|
// ~(c-X) == X-c-1 == X+(-c-1)
|
2004-01-12 19:35:11 +00:00
|
|
|
if (Op0I->getOpcode() == Instruction::Sub && RHS->isAllOnesValue())
|
|
|
|
if (Constant *Op0I0C = dyn_cast<Constant>(Op0I->getOperand(0))) {
|
2004-06-10 02:07:29 +00:00
|
|
|
Constant *NegOp0I0C = ConstantExpr::getNeg(Op0I0C);
|
|
|
|
Constant *ConstantRHS = ConstantExpr::getSub(NegOp0I0C,
|
2004-01-12 19:35:11 +00:00
|
|
|
ConstantInt::get(I.getType(), 1));
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAdd(Op0I->getOperand(1), ConstantRHS);
|
2004-01-12 19:35:11 +00:00
|
|
|
}
|
2004-06-18 06:07:51 +00:00
|
|
|
|
|
|
|
// ~(~X & Y) --> (X | ~Y)
|
|
|
|
if (Op0I->getOpcode() == Instruction::And && RHS->isAllOnesValue()) {
|
|
|
|
if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands();
|
|
|
|
if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) {
|
|
|
|
Instruction *NotY =
|
|
|
|
BinaryOperator::createNot(Op0I->getOperand(1),
|
|
|
|
Op0I->getOperand(1)->getName()+".not");
|
|
|
|
InsertNewInstBefore(NotY, I);
|
|
|
|
return BinaryOperator::createOr(Op0NotVal, NotY);
|
|
|
|
}
|
|
|
|
}
|
2003-07-23 21:37:07 +00:00
|
|
|
|
|
|
|
if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
|
2003-11-04 23:50:51 +00:00
|
|
|
switch (Op0I->getOpcode()) {
|
|
|
|
case Instruction::Add:
|
2003-11-04 23:37:10 +00:00
|
|
|
// ~(X-c) --> (-c-1)-X
|
2004-01-12 19:35:11 +00:00
|
|
|
if (RHS->isAllOnesValue()) {
|
2004-06-10 02:07:29 +00:00
|
|
|
Constant *NegOp0CI = ConstantExpr::getNeg(Op0CI);
|
|
|
|
return BinaryOperator::createSub(
|
|
|
|
ConstantExpr::getSub(NegOp0CI,
|
2004-01-12 19:35:11 +00:00
|
|
|
ConstantInt::get(I.getType(), 1)),
|
2003-11-04 23:37:10 +00:00
|
|
|
Op0I->getOperand(0));
|
2004-01-12 19:35:11 +00:00
|
|
|
}
|
2003-11-04 23:50:51 +00:00
|
|
|
break;
|
|
|
|
case Instruction::And:
|
2003-07-23 21:37:07 +00:00
|
|
|
// (X & C1) ^ C2 --> (X & C1) | C2 iff (C1&C2) == 0
|
2004-06-10 02:07:29 +00:00
|
|
|
if (ConstantExpr::getAnd(RHS, Op0CI)->isNullValue())
|
|
|
|
return BinaryOperator::createOr(Op0, RHS);
|
2003-11-04 23:50:51 +00:00
|
|
|
break;
|
|
|
|
case Instruction::Or:
|
2003-07-23 21:37:07 +00:00
|
|
|
// (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
|
2004-06-10 02:07:29 +00:00
|
|
|
if (ConstantExpr::getAnd(RHS, Op0CI) == RHS)
|
2004-06-10 02:12:35 +00:00
|
|
|
return BinaryOperator::createAnd(Op0, ConstantExpr::getNot(RHS));
|
2003-11-04 23:50:51 +00:00
|
|
|
break;
|
|
|
|
default: break;
|
2003-07-23 21:37:07 +00:00
|
|
|
}
|
2002-08-20 18:24:26 +00:00
|
|
|
}
|
2004-04-09 19:05:30 +00:00
|
|
|
|
|
|
|
// Try to fold constant and into select arguments.
|
|
|
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
|
|
|
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
|
|
|
|
return R;
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
if (isa<PHINode>(Op0))
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
2002-05-06 16:14:14 +00:00
|
|
|
}
|
|
|
|
|
2003-03-10 23:06:50 +00:00
|
|
|
if (Value *X = dyn_castNotVal(Op0)) // ~A ^ A == -1
|
2003-02-18 19:28:33 +00:00
|
|
|
if (X == Op1)
|
|
|
|
return ReplaceInstUsesWith(I,
|
|
|
|
ConstantIntegral::getAllOnesValue(I.getType()));
|
|
|
|
|
2003-03-10 23:06:50 +00:00
|
|
|
if (Value *X = dyn_castNotVal(Op1)) // A ^ ~A == -1
|
2003-02-18 19:28:33 +00:00
|
|
|
if (X == Op0)
|
|
|
|
return ReplaceInstUsesWith(I,
|
|
|
|
ConstantIntegral::getAllOnesValue(I.getType()));
|
|
|
|
|
2003-03-10 18:24:17 +00:00
|
|
|
if (Instruction *Op1I = dyn_cast<Instruction>(Op1))
|
2004-02-16 03:54:20 +00:00
|
|
|
if (Op1I->getOpcode() == Instruction::Or) {
|
2003-03-10 18:24:17 +00:00
|
|
|
if (Op1I->getOperand(0) == Op0) { // B^(B|A) == (A|B)^B
|
|
|
|
cast<BinaryOperator>(Op1I)->swapOperands();
|
|
|
|
I.swapOperands();
|
|
|
|
std::swap(Op0, Op1);
|
|
|
|
} else if (Op1I->getOperand(1) == Op0) { // B^(A|B) == (A|B)^B
|
|
|
|
I.swapOperands();
|
|
|
|
std::swap(Op0, Op1);
|
2004-02-16 03:54:20 +00:00
|
|
|
}
|
|
|
|
} else if (Op1I->getOpcode() == Instruction::Xor) {
|
|
|
|
if (Op0 == Op1I->getOperand(0)) // A^(A^B) == B
|
|
|
|
return ReplaceInstUsesWith(I, Op1I->getOperand(1));
|
|
|
|
else if (Op0 == Op1I->getOperand(1)) // A^(B^A) == B
|
|
|
|
return ReplaceInstUsesWith(I, Op1I->getOperand(0));
|
|
|
|
}
|
2003-03-10 18:24:17 +00:00
|
|
|
|
|
|
|
if (Instruction *Op0I = dyn_cast<Instruction>(Op0))
|
2003-10-15 16:48:29 +00:00
|
|
|
if (Op0I->getOpcode() == Instruction::Or && Op0I->hasOneUse()) {
|
2003-03-10 18:24:17 +00:00
|
|
|
if (Op0I->getOperand(0) == Op1) // (B|A)^B == (A|B)^B
|
|
|
|
cast<BinaryOperator>(Op0I)->swapOperands();
|
2003-03-10 21:43:22 +00:00
|
|
|
if (Op0I->getOperand(1) == Op1) { // (A|B)^B == A & ~B
|
Be more careful about the order we put stuff onto the worklist. This allow us to
collapse this:
bool %le(int %A, int %B) {
%c1 = setgt int %A, %B
%tmp = select bool %c1, int 1, int 0
%c2 = setlt int %A, %B
%result = select bool %c2, int -1, int %tmp
%c3 = setle int %result, 0
ret bool %c3
}
into:
bool %le(int %A, int %B) {
%c3 = setle int %A, %B ; <bool> [#uses=1]
ret bool %c3
}
which is handy, because the Java FE makes these sequences all over the place.
This is tested as: test/Regression/Transforms/InstCombine/JavaCompare.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14086 91177308-0d34-0410-b5e6-96231b3b80d8
2004-06-09 05:08:07 +00:00
|
|
|
Value *NotB = InsertNewInstBefore(BinaryOperator::createNot(Op1,
|
|
|
|
Op1->getName()+".not"), I);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(Op0I->getOperand(0), NotB);
|
2003-03-10 18:24:17 +00:00
|
|
|
}
|
2004-02-16 03:54:20 +00:00
|
|
|
} else if (Op0I->getOpcode() == Instruction::Xor) {
|
|
|
|
if (Op1 == Op0I->getOperand(0)) // (A^B)^A == B
|
|
|
|
return ReplaceInstUsesWith(I, Op0I->getOperand(1));
|
|
|
|
else if (Op1 == Op0I->getOperand(1)) // (B^A)^A == B
|
|
|
|
return ReplaceInstUsesWith(I, Op0I->getOperand(0));
|
2003-03-10 18:24:17 +00:00
|
|
|
}
|
|
|
|
|
2004-08-01 19:42:59 +00:00
|
|
|
// (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
|
2004-07-30 07:50:03 +00:00
|
|
|
Value *A, *B; ConstantInt *C1, *C2;
|
|
|
|
if (match(Op0, m_And(m_Value(A), m_ConstantInt(C1))) &&
|
|
|
|
match(Op1, m_And(m_Value(B), m_ConstantInt(C2))) &&
|
2004-08-01 19:42:59 +00:00
|
|
|
ConstantExpr::getAnd(C1, C2)->isNullValue())
|
2004-07-30 07:50:03 +00:00
|
|
|
return BinaryOperator::createOr(Op0, Op1);
|
2003-03-11 00:12:48 +00:00
|
|
|
|
2003-08-13 20:16:26 +00:00
|
|
|
// (setcc1 A, B) ^ (setcc2 A, B) --> (setcc3 A, B)
|
|
|
|
if (SetCondInst *RHS = dyn_cast<SetCondInst>(I.getOperand(1)))
|
|
|
|
if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
|
|
|
|
return R;
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
return Changed ? &I : 0;
|
2002-05-06 16:14:14 +00:00
|
|
|
}
|
|
|
|
|
2004-09-29 17:40:11 +00:00
|
|
|
/// MulWithOverflow - Compute Result = In1*In2, returning true if the result
|
|
|
|
/// overflowed for this type.
|
|
|
|
static bool MulWithOverflow(ConstantInt *&Result, ConstantInt *In1,
|
|
|
|
ConstantInt *In2) {
|
|
|
|
Result = cast<ConstantInt>(ConstantExpr::getMul(In1, In2));
|
|
|
|
return !In2->isNullValue() && ConstantExpr::getDiv(Result, In2) != In1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isPositive(ConstantInt *C) {
|
|
|
|
return cast<ConstantSInt>(C)->getValue() >= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// AddWithOverflow - Compute Result = In1+In2, returning true if the result
|
|
|
|
/// overflowed for this type.
|
|
|
|
static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1,
|
|
|
|
ConstantInt *In2) {
|
|
|
|
Result = cast<ConstantInt>(ConstantExpr::getAdd(In1, In2));
|
|
|
|
|
|
|
|
if (In1->getType()->isUnsigned())
|
|
|
|
return cast<ConstantUInt>(Result)->getValue() <
|
|
|
|
cast<ConstantUInt>(In1)->getValue();
|
|
|
|
if (isPositive(In1) != isPositive(In2))
|
|
|
|
return false;
|
|
|
|
if (isPositive(In1))
|
|
|
|
return cast<ConstantSInt>(Result)->getValue() <
|
|
|
|
cast<ConstantSInt>(In1)->getValue();
|
|
|
|
return cast<ConstantSInt>(Result)->getValue() >
|
|
|
|
cast<ConstantSInt>(In1)->getValue();
|
|
|
|
}
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
|
2003-03-10 21:43:22 +00:00
|
|
|
bool Changed = SimplifyCommutative(I);
|
2002-08-09 23:47:40 +00:00
|
|
|
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
|
|
|
const Type *Ty = Op0->getType();
|
2002-05-06 16:14:14 +00:00
|
|
|
|
|
|
|
// setcc X, X
|
2002-08-09 23:47:40 +00:00
|
|
|
if (Op0 == Op1)
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::get(isTrueWhenEqual(I)));
|
2002-05-09 20:11:54 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(Op1)) // X setcc undef -> undef
|
|
|
|
return ReplaceInstUsesWith(I, UndefValue::get(Type::BoolTy));
|
|
|
|
|
2004-11-14 07:33:16 +00:00
|
|
|
// setcc <global/alloca*/null>, <global/alloca*/null> - Global/Stack value
|
|
|
|
// addresses never equal each other! We already know that Op0 != Op1.
|
|
|
|
if ((isa<GlobalValue>(Op0) || isa<AllocaInst>(Op0) ||
|
|
|
|
isa<ConstantPointerNull>(Op0)) &&
|
|
|
|
(isa<GlobalValue>(Op1) || isa<AllocaInst>(Op1) ||
|
|
|
|
isa<ConstantPointerNull>(Op1)))
|
2002-08-09 23:47:40 +00:00
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::get(!isTrueWhenEqual(I)));
|
|
|
|
|
|
|
|
// setcc's with boolean values can always be turned into bitwise operations
|
|
|
|
if (Ty == Type::BoolTy) {
|
2004-08-11 00:50:51 +00:00
|
|
|
switch (I.getOpcode()) {
|
|
|
|
default: assert(0 && "Invalid setcc instruction!");
|
|
|
|
case Instruction::SetEQ: { // seteq bool %A, %B -> ~(A^B)
|
2004-06-10 02:07:29 +00:00
|
|
|
Instruction *Xor = BinaryOperator::createXor(Op0, Op1, I.getName()+"tmp");
|
2002-08-09 23:47:40 +00:00
|
|
|
InsertNewInstBefore(Xor, I);
|
2003-11-03 04:25:02 +00:00
|
|
|
return BinaryOperator::createNot(Xor);
|
2002-08-09 23:47:40 +00:00
|
|
|
}
|
2004-08-11 00:50:51 +00:00
|
|
|
case Instruction::SetNE:
|
|
|
|
return BinaryOperator::createXor(Op0, Op1);
|
2002-08-09 23:47:40 +00:00
|
|
|
|
2004-08-11 00:50:51 +00:00
|
|
|
case Instruction::SetGT:
|
|
|
|
std::swap(Op0, Op1); // Change setgt -> setlt
|
|
|
|
// FALL THROUGH
|
|
|
|
case Instruction::SetLT: { // setlt bool A, B -> ~X & Y
|
|
|
|
Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp");
|
|
|
|
InsertNewInstBefore(Not, I);
|
|
|
|
return BinaryOperator::createAnd(Not, Op1);
|
|
|
|
}
|
|
|
|
case Instruction::SetGE:
|
2002-08-09 23:47:40 +00:00
|
|
|
std::swap(Op0, Op1); // Change setge -> setle
|
2004-08-11 00:50:51 +00:00
|
|
|
// FALL THROUGH
|
|
|
|
case Instruction::SetLE: { // setle bool %A, %B -> ~A | B
|
|
|
|
Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp");
|
|
|
|
InsertNewInstBefore(Not, I);
|
|
|
|
return BinaryOperator::createOr(Not, Op1);
|
|
|
|
}
|
|
|
|
}
|
2002-08-09 23:47:40 +00:00
|
|
|
}
|
|
|
|
|
2004-06-09 04:24:29 +00:00
|
|
|
// See if we are doing a comparison between a constant and an instruction that
|
|
|
|
// can be folded into the comparison.
|
2002-08-09 23:47:40 +00:00
|
|
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
2004-09-29 17:40:11 +00:00
|
|
|
// Check to see if we are comparing against the minimum or maximum value...
|
|
|
|
if (CI->isMinValue()) {
|
|
|
|
if (I.getOpcode() == Instruction::SetLT) // A < MIN -> FALSE
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
if (I.getOpcode() == Instruction::SetGE) // A >= MIN -> TRUE
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
if (I.getOpcode() == Instruction::SetLE) // A <= MIN -> A == MIN
|
|
|
|
return BinaryOperator::createSetEQ(Op0, Op1);
|
|
|
|
if (I.getOpcode() == Instruction::SetGT) // A > MIN -> A != MIN
|
|
|
|
return BinaryOperator::createSetNE(Op0, Op1);
|
|
|
|
|
|
|
|
} else if (CI->isMaxValue()) {
|
|
|
|
if (I.getOpcode() == Instruction::SetGT) // A > MAX -> FALSE
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
if (I.getOpcode() == Instruction::SetLE) // A <= MAX -> TRUE
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
if (I.getOpcode() == Instruction::SetGE) // A >= MAX -> A == MAX
|
|
|
|
return BinaryOperator::createSetEQ(Op0, Op1);
|
|
|
|
if (I.getOpcode() == Instruction::SetLT) // A < MAX -> A != MAX
|
|
|
|
return BinaryOperator::createSetNE(Op0, Op1);
|
|
|
|
|
|
|
|
// Comparing against a value really close to min or max?
|
|
|
|
} else if (isMinValuePlusOne(CI)) {
|
|
|
|
if (I.getOpcode() == Instruction::SetLT) // A < MIN+1 -> A == MIN
|
|
|
|
return BinaryOperator::createSetEQ(Op0, SubOne(CI));
|
|
|
|
if (I.getOpcode() == Instruction::SetGE) // A >= MIN-1 -> A != MIN
|
|
|
|
return BinaryOperator::createSetNE(Op0, SubOne(CI));
|
|
|
|
|
|
|
|
} else if (isMaxValueMinusOne(CI)) {
|
|
|
|
if (I.getOpcode() == Instruction::SetGT) // A > MAX-1 -> A == MAX
|
|
|
|
return BinaryOperator::createSetEQ(Op0, AddOne(CI));
|
|
|
|
if (I.getOpcode() == Instruction::SetLE) // A <= MAX-1 -> A != MAX
|
|
|
|
return BinaryOperator::createSetNE(Op0, AddOne(CI));
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we still have a setle or setge instruction, turn it into the
|
|
|
|
// appropriate setlt or setgt instruction. Since the border cases have
|
|
|
|
// already been handled above, this requires little checking.
|
|
|
|
//
|
|
|
|
if (I.getOpcode() == Instruction::SetLE)
|
|
|
|
return BinaryOperator::createSetLT(Op0, AddOne(CI));
|
|
|
|
if (I.getOpcode() == Instruction::SetGE)
|
|
|
|
return BinaryOperator::createSetGT(Op0, SubOne(CI));
|
|
|
|
|
2004-05-25 06:32:08 +00:00
|
|
|
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
|
2004-09-23 21:52:49 +00:00
|
|
|
switch (LHSI->getOpcode()) {
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
case Instruction::PHI:
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
|
|
|
break;
|
2004-09-23 21:52:49 +00:00
|
|
|
case Instruction::And:
|
|
|
|
if (LHSI->hasOneUse() && isa<ConstantInt>(LHSI->getOperand(1)) &&
|
|
|
|
LHSI->getOperand(0)->hasOneUse()) {
|
|
|
|
// If this is: (X >> C1) & C2 != C3 (where any shift and any compare
|
|
|
|
// could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This
|
|
|
|
// happens a LOT in code produced by the C front-end, for bitfield
|
|
|
|
// access.
|
|
|
|
ShiftInst *Shift = dyn_cast<ShiftInst>(LHSI->getOperand(0));
|
|
|
|
ConstantUInt *ShAmt;
|
|
|
|
ShAmt = Shift ? dyn_cast<ConstantUInt>(Shift->getOperand(1)) : 0;
|
|
|
|
ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
|
|
|
|
const Type *Ty = LHSI->getType();
|
|
|
|
|
|
|
|
// We can fold this as long as we can't shift unknown bits
|
|
|
|
// into the mask. This can only happen with signed shift
|
|
|
|
// rights, as they sign-extend.
|
|
|
|
if (ShAmt) {
|
|
|
|
bool CanFold = Shift->getOpcode() != Instruction::Shr ||
|
2004-09-28 17:54:07 +00:00
|
|
|
Shift->getType()->isUnsigned();
|
2004-09-23 21:52:49 +00:00
|
|
|
if (!CanFold) {
|
|
|
|
// To test for the bad case of the signed shr, see if any
|
|
|
|
// of the bits shifted in could be tested after the mask.
|
|
|
|
Constant *OShAmt = ConstantUInt::get(Type::UByteTy,
|
2004-07-21 20:14:10 +00:00
|
|
|
Ty->getPrimitiveSize()*8-ShAmt->getValue());
|
2004-09-23 21:52:49 +00:00
|
|
|
Constant *ShVal =
|
|
|
|
ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), OShAmt);
|
|
|
|
if (ConstantExpr::getAnd(ShVal, AndCST)->isNullValue())
|
|
|
|
CanFold = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CanFold) {
|
2004-09-28 17:54:07 +00:00
|
|
|
Constant *NewCst;
|
|
|
|
if (Shift->getOpcode() == Instruction::Shl)
|
|
|
|
NewCst = ConstantExpr::getUShr(CI, ShAmt);
|
|
|
|
else
|
|
|
|
NewCst = ConstantExpr::getShl(CI, ShAmt);
|
2004-09-27 19:29:18 +00:00
|
|
|
|
2004-09-23 21:52:49 +00:00
|
|
|
// Check to see if we are shifting out any of the bits being
|
|
|
|
// compared.
|
|
|
|
if (ConstantExpr::get(Shift->getOpcode(), NewCst, ShAmt) != CI){
|
|
|
|
// If we shifted bits out, the fold is not going to work out.
|
|
|
|
// As a special case, check to see if this means that the
|
|
|
|
// result is always true or false now.
|
|
|
|
if (I.getOpcode() == Instruction::SetEQ)
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
if (I.getOpcode() == Instruction::SetNE)
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
} else {
|
|
|
|
I.setOperand(1, NewCst);
|
2004-09-28 17:54:07 +00:00
|
|
|
Constant *NewAndCST;
|
|
|
|
if (Shift->getOpcode() == Instruction::Shl)
|
|
|
|
NewAndCST = ConstantExpr::getUShr(AndCST, ShAmt);
|
|
|
|
else
|
|
|
|
NewAndCST = ConstantExpr::getShl(AndCST, ShAmt);
|
|
|
|
LHSI->setOperand(1, NewAndCST);
|
2004-09-23 21:52:49 +00:00
|
|
|
LHSI->setOperand(0, Shift->getOperand(0));
|
|
|
|
WorkList.push_back(Shift); // Shift is dead.
|
|
|
|
AddUsesToWorkList(I);
|
|
|
|
return &I;
|
2004-07-21 19:50:44 +00:00
|
|
|
}
|
|
|
|
}
|
2004-06-09 07:59:58 +00:00
|
|
|
}
|
2004-09-23 21:52:49 +00:00
|
|
|
}
|
|
|
|
break;
|
2004-09-27 19:29:18 +00:00
|
|
|
|
2004-11-28 21:31:15 +00:00
|
|
|
// (setcc (cast X to larger), CI)
|
|
|
|
case Instruction::Cast: {
|
|
|
|
Instruction* replacement =
|
|
|
|
visitSetCondInstWithCastAndConstant(I,cast<CastInst>(LHSI),CI);
|
|
|
|
if (replacement)
|
|
|
|
return replacement;
|
2004-09-29 03:09:18 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-11-28 21:31:15 +00:00
|
|
|
|
2004-09-28 18:22:15 +00:00
|
|
|
case Instruction::Shl: // (setcc (shl X, ShAmt), CI)
|
|
|
|
if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
|
|
|
|
switch (I.getOpcode()) {
|
|
|
|
default: break;
|
|
|
|
case Instruction::SetEQ:
|
|
|
|
case Instruction::SetNE: {
|
|
|
|
// If we are comparing against bits always shifted out, the
|
|
|
|
// comparison cannot succeed.
|
|
|
|
Constant *Comp =
|
|
|
|
ConstantExpr::getShl(ConstantExpr::getShr(CI, ShAmt), ShAmt);
|
|
|
|
if (Comp != CI) {// Comparing against a bit that we know is zero.
|
|
|
|
bool IsSetNE = I.getOpcode() == Instruction::SetNE;
|
|
|
|
Constant *Cst = ConstantBool::get(IsSetNE);
|
|
|
|
return ReplaceInstUsesWith(I, Cst);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LHSI->hasOneUse()) {
|
|
|
|
// Otherwise strength reduce the shift into an and.
|
|
|
|
unsigned ShAmtVal = ShAmt->getValue();
|
|
|
|
unsigned TypeBits = CI->getType()->getPrimitiveSize()*8;
|
|
|
|
uint64_t Val = (1ULL << (TypeBits-ShAmtVal))-1;
|
|
|
|
|
|
|
|
Constant *Mask;
|
|
|
|
if (CI->getType()->isUnsigned()) {
|
|
|
|
Mask = ConstantUInt::get(CI->getType(), Val);
|
|
|
|
} else if (ShAmtVal != 0) {
|
|
|
|
Mask = ConstantSInt::get(CI->getType(), Val);
|
|
|
|
} else {
|
|
|
|
Mask = ConstantInt::getAllOnesValue(CI->getType());
|
|
|
|
}
|
|
|
|
|
|
|
|
Instruction *AndI =
|
|
|
|
BinaryOperator::createAnd(LHSI->getOperand(0),
|
|
|
|
Mask, LHSI->getName()+".mask");
|
|
|
|
Value *And = InsertNewInstBefore(AndI, I);
|
|
|
|
return new SetCondInst(I.getOpcode(), And,
|
|
|
|
ConstantExpr::getUShr(CI, ShAmt));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2004-09-27 19:29:18 +00:00
|
|
|
case Instruction::Shr: // (setcc (shr X, ShAmt), CI)
|
Fold: (setcc (shr X, ShAmt), CI), where 'cc' is eq or ne. This xform
triggers often, for example:
6x in povray, 1x in gzip, 279x in gcc, 1x in crafty, 8x in eon, 11x in perlbmk,
362x in gap, 4x in vortex, 14 in m88ksim, 211x in 126.gcc, 1x in compress,
11x in ijpeg, and 4x in 147.vortex.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16521 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-27 16:18:50 +00:00
|
|
|
if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
|
|
|
|
switch (I.getOpcode()) {
|
|
|
|
default: break;
|
|
|
|
case Instruction::SetEQ:
|
|
|
|
case Instruction::SetNE: {
|
|
|
|
// If we are comparing against bits always shifted out, the
|
|
|
|
// comparison cannot succeed.
|
|
|
|
Constant *Comp =
|
|
|
|
ConstantExpr::getShr(ConstantExpr::getShl(CI, ShAmt), ShAmt);
|
|
|
|
|
|
|
|
if (Comp != CI) {// Comparing against a bit that we know is zero.
|
|
|
|
bool IsSetNE = I.getOpcode() == Instruction::SetNE;
|
|
|
|
Constant *Cst = ConstantBool::get(IsSetNE);
|
|
|
|
return ReplaceInstUsesWith(I, Cst);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LHSI->hasOneUse() || CI->isNullValue()) {
|
2004-09-28 18:22:15 +00:00
|
|
|
unsigned ShAmtVal = ShAmt->getValue();
|
|
|
|
|
Fold: (setcc (shr X, ShAmt), CI), where 'cc' is eq or ne. This xform
triggers often, for example:
6x in povray, 1x in gzip, 279x in gcc, 1x in crafty, 8x in eon, 11x in perlbmk,
362x in gap, 4x in vortex, 14 in m88ksim, 211x in 126.gcc, 1x in compress,
11x in ijpeg, and 4x in 147.vortex.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16521 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-27 16:18:50 +00:00
|
|
|
// Otherwise strength reduce the shift into an and.
|
|
|
|
uint64_t Val = ~0ULL; // All ones.
|
|
|
|
Val <<= ShAmtVal; // Shift over to the right spot.
|
|
|
|
|
|
|
|
Constant *Mask;
|
|
|
|
if (CI->getType()->isUnsigned()) {
|
|
|
|
unsigned TypeBits = CI->getType()->getPrimitiveSize()*8;
|
|
|
|
Val &= (1ULL << TypeBits)-1;
|
|
|
|
Mask = ConstantUInt::get(CI->getType(), Val);
|
|
|
|
} else {
|
|
|
|
Mask = ConstantSInt::get(CI->getType(), Val);
|
|
|
|
}
|
|
|
|
|
|
|
|
Instruction *AndI =
|
|
|
|
BinaryOperator::createAnd(LHSI->getOperand(0),
|
|
|
|
Mask, LHSI->getName()+".mask");
|
|
|
|
Value *And = InsertNewInstBefore(AndI, I);
|
|
|
|
return new SetCondInst(I.getOpcode(), And,
|
|
|
|
ConstantExpr::getShl(CI, ShAmt));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-09-24 15:21:34 +00:00
|
|
|
|
2004-09-29 17:40:11 +00:00
|
|
|
case Instruction::Div:
|
|
|
|
// Fold: (div X, C1) op C2 -> range check
|
|
|
|
if (ConstantInt *DivRHS = dyn_cast<ConstantInt>(LHSI->getOperand(1))) {
|
|
|
|
// Fold this div into the comparison, producing a range check.
|
|
|
|
// Determine, based on the divide type, what the range is being
|
|
|
|
// checked. If there is an overflow on the low or high side, remember
|
|
|
|
// it, otherwise compute the range [low, hi) bounding the new value.
|
|
|
|
bool LoOverflow = false, HiOverflow = 0;
|
|
|
|
ConstantInt *LoBound = 0, *HiBound = 0;
|
|
|
|
|
|
|
|
ConstantInt *Prod;
|
|
|
|
bool ProdOV = MulWithOverflow(Prod, CI, DivRHS);
|
|
|
|
|
2004-10-11 19:40:04 +00:00
|
|
|
Instruction::BinaryOps Opcode = I.getOpcode();
|
|
|
|
|
2004-09-29 17:40:11 +00:00
|
|
|
if (DivRHS->isNullValue()) { // Don't hack on divide by zeros.
|
|
|
|
} else if (LHSI->getType()->isUnsigned()) { // udiv
|
|
|
|
LoBound = Prod;
|
|
|
|
LoOverflow = ProdOV;
|
|
|
|
HiOverflow = ProdOV || AddWithOverflow(HiBound, LoBound, DivRHS);
|
|
|
|
} else if (isPositive(DivRHS)) { // Divisor is > 0.
|
|
|
|
if (CI->isNullValue()) { // (X / pos) op 0
|
|
|
|
// Can't overflow.
|
|
|
|
LoBound = cast<ConstantInt>(ConstantExpr::getNeg(SubOne(DivRHS)));
|
|
|
|
HiBound = DivRHS;
|
|
|
|
} else if (isPositive(CI)) { // (X / pos) op pos
|
|
|
|
LoBound = Prod;
|
|
|
|
LoOverflow = ProdOV;
|
|
|
|
HiOverflow = ProdOV || AddWithOverflow(HiBound, Prod, DivRHS);
|
|
|
|
} else { // (X / pos) op neg
|
|
|
|
Constant *DivRHSH = ConstantExpr::getNeg(SubOne(DivRHS));
|
|
|
|
LoOverflow = AddWithOverflow(LoBound, Prod,
|
|
|
|
cast<ConstantInt>(DivRHSH));
|
|
|
|
HiBound = Prod;
|
|
|
|
HiOverflow = ProdOV;
|
|
|
|
}
|
|
|
|
} else { // Divisor is < 0.
|
|
|
|
if (CI->isNullValue()) { // (X / neg) op 0
|
|
|
|
LoBound = AddOne(DivRHS);
|
|
|
|
HiBound = cast<ConstantInt>(ConstantExpr::getNeg(DivRHS));
|
|
|
|
} else if (isPositive(CI)) { // (X / neg) op pos
|
|
|
|
HiOverflow = LoOverflow = ProdOV;
|
|
|
|
if (!LoOverflow)
|
|
|
|
LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS));
|
|
|
|
HiBound = AddOne(Prod);
|
|
|
|
} else { // (X / neg) op neg
|
|
|
|
LoBound = Prod;
|
|
|
|
LoOverflow = HiOverflow = ProdOV;
|
|
|
|
HiBound = cast<ConstantInt>(ConstantExpr::getSub(Prod, DivRHS));
|
|
|
|
}
|
2004-10-08 19:15:44 +00:00
|
|
|
|
2004-10-11 19:40:04 +00:00
|
|
|
// Dividing by a negate swaps the condition.
|
|
|
|
Opcode = SetCondInst::getSwappedCondition(Opcode);
|
2004-09-29 17:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (LoBound) {
|
|
|
|
Value *X = LHSI->getOperand(0);
|
2004-10-11 19:40:04 +00:00
|
|
|
switch (Opcode) {
|
2004-09-29 17:40:11 +00:00
|
|
|
default: assert(0 && "Unhandled setcc opcode!");
|
|
|
|
case Instruction::SetEQ:
|
|
|
|
if (LoOverflow && HiOverflow)
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
else if (HiOverflow)
|
|
|
|
return new SetCondInst(Instruction::SetGE, X, LoBound);
|
|
|
|
else if (LoOverflow)
|
|
|
|
return new SetCondInst(Instruction::SetLT, X, HiBound);
|
|
|
|
else
|
|
|
|
return InsertRangeTest(X, LoBound, HiBound, true, I);
|
|
|
|
case Instruction::SetNE:
|
|
|
|
if (LoOverflow && HiOverflow)
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
else if (HiOverflow)
|
|
|
|
return new SetCondInst(Instruction::SetLT, X, LoBound);
|
|
|
|
else if (LoOverflow)
|
|
|
|
return new SetCondInst(Instruction::SetGE, X, HiBound);
|
|
|
|
else
|
|
|
|
return InsertRangeTest(X, LoBound, HiBound, false, I);
|
|
|
|
case Instruction::SetLT:
|
|
|
|
if (LoOverflow)
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
return new SetCondInst(Instruction::SetLT, X, LoBound);
|
|
|
|
case Instruction::SetGT:
|
|
|
|
if (HiOverflow)
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
return new SetCondInst(Instruction::SetGE, X, HiBound);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-09-23 21:52:49 +00:00
|
|
|
case Instruction::Select:
|
|
|
|
// If either operand of the select is a constant, we can fold the
|
|
|
|
// comparison into the select arms, which will cause one to be
|
|
|
|
// constant folded and the select turned into a bitwise or.
|
|
|
|
Value *Op1 = 0, *Op2 = 0;
|
|
|
|
if (LHSI->hasOneUse()) {
|
2004-06-09 07:59:58 +00:00
|
|
|
if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(1))) {
|
2004-06-09 04:24:29 +00:00
|
|
|
// Fold the known value into the constant operand.
|
|
|
|
Op1 = ConstantExpr::get(I.getOpcode(), C, CI);
|
|
|
|
// Insert a new SetCC of the other select operand.
|
|
|
|
Op2 = InsertNewInstBefore(new SetCondInst(I.getOpcode(),
|
2004-06-09 07:59:58 +00:00
|
|
|
LHSI->getOperand(2), CI,
|
2004-06-09 04:24:29 +00:00
|
|
|
I.getName()), I);
|
2004-06-09 07:59:58 +00:00
|
|
|
} else if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(2))) {
|
2004-06-09 04:24:29 +00:00
|
|
|
// Fold the known value into the constant operand.
|
|
|
|
Op2 = ConstantExpr::get(I.getOpcode(), C, CI);
|
|
|
|
// Insert a new SetCC of the other select operand.
|
|
|
|
Op1 = InsertNewInstBefore(new SetCondInst(I.getOpcode(),
|
2004-06-09 07:59:58 +00:00
|
|
|
LHSI->getOperand(1), CI,
|
2004-06-09 04:24:29 +00:00
|
|
|
I.getName()), I);
|
|
|
|
}
|
|
|
|
}
|
2004-09-23 21:52:49 +00:00
|
|
|
|
|
|
|
if (Op1)
|
|
|
|
return new SelectInst(LHSI->getOperand(0), Op1, Op2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-07-23 17:02:11 +00:00
|
|
|
// Simplify seteq and setne instructions...
|
|
|
|
if (I.getOpcode() == Instruction::SetEQ ||
|
|
|
|
I.getOpcode() == Instruction::SetNE) {
|
|
|
|
bool isSetNE = I.getOpcode() == Instruction::SetNE;
|
|
|
|
|
2003-07-23 17:26:36 +00:00
|
|
|
// If the first operand is (and|or|xor) with a constant, and the second
|
2003-07-23 17:02:11 +00:00
|
|
|
// operand is a constant, simplify a bit.
|
2003-08-13 05:33:12 +00:00
|
|
|
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0)) {
|
|
|
|
switch (BO->getOpcode()) {
|
2004-07-06 07:38:18 +00:00
|
|
|
case Instruction::Rem:
|
|
|
|
// If we have a signed (X % (2^c)) == 0, turn it into an unsigned one.
|
|
|
|
if (CI->isNullValue() && isa<ConstantSInt>(BO->getOperand(1)) &&
|
|
|
|
BO->hasOneUse() &&
|
|
|
|
cast<ConstantSInt>(BO->getOperand(1))->getValue() > 1)
|
|
|
|
if (unsigned L2 =
|
|
|
|
Log2(cast<ConstantSInt>(BO->getOperand(1))->getValue())) {
|
|
|
|
const Type *UTy = BO->getType()->getUnsignedVersion();
|
|
|
|
Value *NewX = InsertNewInstBefore(new CastInst(BO->getOperand(0),
|
|
|
|
UTy, "tmp"), I);
|
|
|
|
Constant *RHSCst = ConstantUInt::get(UTy, 1ULL << L2);
|
|
|
|
Value *NewRem =InsertNewInstBefore(BinaryOperator::createRem(NewX,
|
|
|
|
RHSCst, BO->getName()), I);
|
|
|
|
return BinaryOperator::create(I.getOpcode(), NewRem,
|
|
|
|
Constant::getNullValue(UTy));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2003-08-13 05:33:12 +00:00
|
|
|
case Instruction::Add:
|
2004-06-27 22:51:36 +00:00
|
|
|
// Replace ((add A, B) != C) with (A != C-B) if B & C are constants.
|
|
|
|
if (ConstantInt *BOp1C = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
Do not fold (X + C1 != C2) if there are other users of the add. Doing
this transformation used to take a loop like this:
int Array[1000];
void test(int X) {
int i;
for (i = 0; i < 1000; ++i)
Array[i] += X;
}
Compiled to LLVM is:
no_exit: ; preds = %entry, %no_exit
%indvar = phi uint [ 0, %entry ], [ %indvar.next, %no_exit ] ; <uint> [#uses=2]
%tmp.4 = getelementptr [1000 x int]* %Array, int 0, uint %indvar ; <int*> [#uses=2]
%tmp.7 = load int* %tmp.4 ; <int> [#uses=1]
%tmp.9 = add int %tmp.7, %X ; <int> [#uses=1]
store int %tmp.9, int* %tmp.4
*** %indvar.next = add uint %indvar, 1 ; <uint> [#uses=2]
*** %exitcond = seteq uint %indvar.next, 1000 ; <bool> [#uses=1]
br bool %exitcond, label %return, label %no_exit
and turn it into a loop like this:
no_exit: ; preds = %entry, %no_exit
%indvar = phi uint [ 0, %entry ], [ %indvar.next, %no_exit ] ; <uint> [#uses=3]
%tmp.4 = getelementptr [1000 x int]* %Array, int 0, uint %indvar ; <int*> [#uses=2]
%tmp.7 = load int* %tmp.4 ; <int> [#uses=1]
%tmp.9 = add int %tmp.7, %X ; <int> [#uses=1]
store int %tmp.9, int* %tmp.4
*** %indvar.next = add uint %indvar, 1 ; <uint> [#uses=1]
*** %exitcond = seteq uint %indvar, 999 ; <bool> [#uses=1]
br bool %exitcond, label %return, label %no_exit
Note that indvar.next and indvar can no longer be coallesced. In machine
code terms, this patch changes this code:
.LBBtest_1: # no_exit
mov %EDX, OFFSET Array
mov %ESI, %EAX
add %ESI, DWORD PTR [%EDX + 4*%ECX]
mov %EDX, OFFSET Array
mov DWORD PTR [%EDX + 4*%ECX], %ESI
mov %EDX, %ECX
inc %EDX
cmp %ECX, 999
mov %ECX, %EDX
jne .LBBtest_1 # no_exit
into this:
.LBBtest_1: # no_exit
mov %EDX, OFFSET Array
mov %ESI, %EAX
add %ESI, DWORD PTR [%EDX + 4*%ECX]
mov %EDX, OFFSET Array
mov DWORD PTR [%EDX + 4*%ECX], %ESI
inc %ECX
cmp %ECX, 1000
jne .LBBtest_1 # no_exit
We need better instruction selection to get this:
.LBBtest_1: # no_exit
add DWORD PTR [Array + 4*%ECX], EAX
inc %ECX
cmp %ECX, 1000
jne .LBBtest_1 # no_exit
... but at least there is less register juggling
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16473 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-21 21:35:23 +00:00
|
|
|
if (BO->hasOneUse())
|
|
|
|
return new SetCondInst(I.getOpcode(), BO->getOperand(0),
|
|
|
|
ConstantExpr::getSub(CI, BOp1C));
|
2004-06-27 22:51:36 +00:00
|
|
|
} else if (CI->isNullValue()) {
|
2003-08-13 05:33:12 +00:00
|
|
|
// Replace ((add A, B) != 0) with (A != -B) if A or B is
|
|
|
|
// efficiently invertible, or if the add has just this one use.
|
|
|
|
Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1);
|
2004-06-27 22:51:36 +00:00
|
|
|
|
2003-08-13 05:33:12 +00:00
|
|
|
if (Value *NegVal = dyn_castNegVal(BOp1))
|
|
|
|
return new SetCondInst(I.getOpcode(), BOp0, NegVal);
|
|
|
|
else if (Value *NegVal = dyn_castNegVal(BOp0))
|
|
|
|
return new SetCondInst(I.getOpcode(), NegVal, BOp1);
|
2003-10-15 16:48:29 +00:00
|
|
|
else if (BO->hasOneUse()) {
|
2003-08-13 05:33:12 +00:00
|
|
|
Instruction *Neg = BinaryOperator::createNeg(BOp1, BO->getName());
|
|
|
|
BO->setName("");
|
|
|
|
InsertNewInstBefore(Neg, I);
|
|
|
|
return new SetCondInst(I.getOpcode(), BOp0, Neg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Instruction::Xor:
|
|
|
|
// For the xor case, we can xor two constants together, eliminating
|
|
|
|
// the explicit xor.
|
|
|
|
if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1)))
|
|
|
|
return BinaryOperator::create(I.getOpcode(), BO->getOperand(0),
|
2004-06-10 02:07:29 +00:00
|
|
|
ConstantExpr::getXor(CI, BOC));
|
2003-08-13 05:33:12 +00:00
|
|
|
|
|
|
|
// FALLTHROUGH
|
|
|
|
case Instruction::Sub:
|
|
|
|
// Replace (([sub|xor] A, B) != 0) with (A != B)
|
|
|
|
if (CI->isNullValue())
|
|
|
|
return new SetCondInst(I.getOpcode(), BO->getOperand(0),
|
|
|
|
BO->getOperand(1));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Instruction::Or:
|
|
|
|
// If bits are being or'd in that are not present in the constant we
|
|
|
|
// are comparing against, then the comparison could never succeed!
|
2004-01-12 19:35:11 +00:00
|
|
|
if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1))) {
|
2004-06-10 02:12:35 +00:00
|
|
|
Constant *NotCI = ConstantExpr::getNot(CI);
|
2004-06-10 02:07:29 +00:00
|
|
|
if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue())
|
2003-07-23 17:02:11 +00:00
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::get(isSetNE));
|
2004-01-12 19:35:11 +00:00
|
|
|
}
|
2003-08-13 05:33:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case Instruction::And:
|
|
|
|
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
2003-07-23 17:02:11 +00:00
|
|
|
// If bits are being compared against that are and'd out, then the
|
|
|
|
// comparison can never succeed!
|
2004-06-10 02:12:35 +00:00
|
|
|
if (!ConstantExpr::getAnd(CI,
|
|
|
|
ConstantExpr::getNot(BOC))->isNullValue())
|
2003-07-23 17:02:11 +00:00
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::get(isSetNE));
|
2003-08-13 05:33:12 +00:00
|
|
|
|
2004-06-09 07:59:58 +00:00
|
|
|
// If we have ((X & C) == C), turn it into ((X & C) != 0).
|
Fix a bug in my checkin from last night that caused miscompilations of
186.crafty, fhourstones and 132.ijpeg.
Bugpoint makes really nasty miscompilations embarassingly easy to find. It
narrowed it down to the instcombiner and this testcase (from fhourstones):
bool %l7153_l4706_htstat_loopentry_2E_4_no_exit_2E_4(int* %i, [32 x int]* %works, int* %tmp.98.out) {
newFuncRoot:
%tmp.96 = load int* %i ; <int> [#uses=1]
%tmp.97 = getelementptr [32 x int]* %works, long 0, int %tmp.96 ; <int*> [#uses=1]
%tmp.98 = load int* %tmp.97 ; <int> [#uses=2]
%tmp.99 = load int* %i ; <int> [#uses=1]
%tmp.100 = and int %tmp.99, 7 ; <int> [#uses=1]
%tmp.101 = seteq int %tmp.100, 7 ; <bool> [#uses=2]
%tmp.102 = cast bool %tmp.101 to int ; <int> [#uses=0]
br bool %tmp.101, label %codeRepl4.exitStub, label %codeRepl3.exitStub
codeRepl4.exitStub: ; preds = %newFuncRoot
store int %tmp.98, int* %tmp.98.out
ret bool true
codeRepl3.exitStub: ; preds = %newFuncRoot
store int %tmp.98, int* %tmp.98.out
ret bool false
}
... which only has one combination performed on it:
$ llvm-as < t.ll | opt -instcombine -debug | llvm-dis
IC: Old = %tmp.101 = seteq int %tmp.100, 7 ; <bool> [#uses=1]
New = setne int %tmp.100, 0 ; <bool>:<badref> [#uses=0]
IC: MOD = br bool %tmp.101, label %codeRepl3.exitStub, label %codeRepl4.exitStub
IC: MOD = %tmp.97 = getelementptr [32 x int]* %works, uint 0, int %tmp.96 ; <int*> [#uses=1]
It doesn't get much better than this. :)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14109 91177308-0d34-0410-b5e6-96231b3b80d8
2004-06-10 02:33:20 +00:00
|
|
|
if (CI == BOC && isOneBitSet(CI))
|
2004-06-09 07:59:58 +00:00
|
|
|
return new SetCondInst(isSetNE ? Instruction::SetEQ :
|
|
|
|
Instruction::SetNE, Op0,
|
|
|
|
Constant::getNullValue(CI->getType()));
|
|
|
|
|
2003-08-13 05:33:12 +00:00
|
|
|
// Replace (and X, (1 << size(X)-1) != 0) with x < 0, converting X
|
|
|
|
// to be a signed value as appropriate.
|
|
|
|
if (isSignBit(BOC)) {
|
|
|
|
Value *X = BO->getOperand(0);
|
|
|
|
// If 'X' is not signed, insert a cast now...
|
|
|
|
if (!BOC->getType()->isSigned()) {
|
2004-06-17 18:16:02 +00:00
|
|
|
const Type *DestTy = BOC->getType()->getSignedVersion();
|
2004-09-27 19:29:18 +00:00
|
|
|
X = InsertCastBefore(X, DestTy, I);
|
2003-08-13 05:33:12 +00:00
|
|
|
}
|
|
|
|
return new SetCondInst(isSetNE ? Instruction::SetLT :
|
|
|
|
Instruction::SetGE, X,
|
|
|
|
Constant::getNullValue(X->getType()));
|
|
|
|
}
|
2004-09-23 21:46:38 +00:00
|
|
|
|
2004-09-27 19:29:18 +00:00
|
|
|
// ((X & ~7) == 0) --> X < 8
|
2004-09-23 21:46:38 +00:00
|
|
|
if (CI->isNullValue() && isHighOnes(BOC)) {
|
|
|
|
Value *X = BO->getOperand(0);
|
2004-09-27 19:29:18 +00:00
|
|
|
Constant *NegX = ConstantExpr::getNeg(BOC);
|
2004-09-23 21:46:38 +00:00
|
|
|
|
|
|
|
// If 'X' is signed, insert a cast now.
|
2004-09-27 19:29:18 +00:00
|
|
|
if (NegX->getType()->isSigned()) {
|
|
|
|
const Type *DestTy = NegX->getType()->getUnsignedVersion();
|
|
|
|
X = InsertCastBefore(X, DestTy, I);
|
|
|
|
NegX = ConstantExpr::getCast(NegX, DestTy);
|
2004-09-23 21:46:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return new SetCondInst(isSetNE ? Instruction::SetGE :
|
2004-09-27 19:29:18 +00:00
|
|
|
Instruction::SetLT, X, NegX);
|
2004-09-23 21:46:38 +00:00
|
|
|
}
|
|
|
|
|
2003-07-23 17:02:11 +00:00
|
|
|
}
|
2003-08-13 05:33:12 +00:00
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
2004-02-23 07:16:20 +00:00
|
|
|
} else { // Not a SetEQ/SetNE
|
|
|
|
// If the LHS is a cast from an integral value of the same size,
|
|
|
|
if (CastInst *Cast = dyn_cast<CastInst>(Op0)) {
|
|
|
|
Value *CastOp = Cast->getOperand(0);
|
|
|
|
const Type *SrcTy = CastOp->getType();
|
|
|
|
unsigned SrcTySize = SrcTy->getPrimitiveSize();
|
|
|
|
if (SrcTy != Cast->getType() && SrcTy->isInteger() &&
|
|
|
|
SrcTySize == Cast->getType()->getPrimitiveSize()) {
|
|
|
|
assert((SrcTy->isSigned() ^ Cast->getType()->isSigned()) &&
|
|
|
|
"Source and destination signednesses should differ!");
|
|
|
|
if (Cast->getType()->isSigned()) {
|
|
|
|
// If this is a signed comparison, check for comparisons in the
|
|
|
|
// vicinity of zero.
|
|
|
|
if (I.getOpcode() == Instruction::SetLT && CI->isNullValue())
|
|
|
|
// X < 0 => x > 127
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetGT(CastOp,
|
2004-02-23 07:16:20 +00:00
|
|
|
ConstantUInt::get(SrcTy, (1ULL << (SrcTySize*8-1))-1));
|
|
|
|
else if (I.getOpcode() == Instruction::SetGT &&
|
|
|
|
cast<ConstantSInt>(CI)->getValue() == -1)
|
|
|
|
// X > -1 => x < 128
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetLT(CastOp,
|
2004-02-23 07:16:20 +00:00
|
|
|
ConstantUInt::get(SrcTy, 1ULL << (SrcTySize*8-1)));
|
|
|
|
} else {
|
|
|
|
ConstantUInt *CUI = cast<ConstantUInt>(CI);
|
|
|
|
if (I.getOpcode() == Instruction::SetLT &&
|
|
|
|
CUI->getValue() == 1ULL << (SrcTySize*8-1))
|
|
|
|
// X < 128 => X > -1
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetGT(CastOp,
|
|
|
|
ConstantSInt::get(SrcTy, -1));
|
2004-02-23 07:16:20 +00:00
|
|
|
else if (I.getOpcode() == Instruction::SetGT &&
|
|
|
|
CUI->getValue() == (1ULL << (SrcTySize*8-1))-1)
|
|
|
|
// X > 127 => X < 0
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetLT(CastOp,
|
|
|
|
Constant::getNullValue(SrcTy));
|
2004-02-23 07:16:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-06-04 05:10:11 +00:00
|
|
|
}
|
2002-05-06 16:14:14 +00:00
|
|
|
}
|
|
|
|
|
2003-11-03 04:25:02 +00:00
|
|
|
// Test to see if the operands of the setcc are casted versions of other
|
|
|
|
// values. If the cast can be stripped off both arguments, we do so now.
|
2003-11-03 05:17:03 +00:00
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(Op0)) {
|
|
|
|
Value *CastOp0 = CI->getOperand(0);
|
|
|
|
if (CastOp0->getType()->isLosslesslyConvertibleTo(CI->getType()) &&
|
2004-03-13 23:54:27 +00:00
|
|
|
(isa<Constant>(Op1) || isa<CastInst>(Op1)) &&
|
2003-11-03 04:25:02 +00:00
|
|
|
(I.getOpcode() == Instruction::SetEQ ||
|
|
|
|
I.getOpcode() == Instruction::SetNE)) {
|
|
|
|
// We keep moving the cast from the left operand over to the right
|
|
|
|
// operand, where it can often be eliminated completely.
|
2003-11-03 05:17:03 +00:00
|
|
|
Op0 = CastOp0;
|
2003-11-03 04:25:02 +00:00
|
|
|
|
|
|
|
// If operand #1 is a cast instruction, see if we can eliminate it as
|
|
|
|
// well.
|
2003-11-03 05:17:03 +00:00
|
|
|
if (CastInst *CI2 = dyn_cast<CastInst>(Op1))
|
|
|
|
if (CI2->getOperand(0)->getType()->isLosslesslyConvertibleTo(
|
2003-11-03 04:25:02 +00:00
|
|
|
Op0->getType()))
|
2003-11-03 05:17:03 +00:00
|
|
|
Op1 = CI2->getOperand(0);
|
2003-11-03 04:25:02 +00:00
|
|
|
|
|
|
|
// If Op1 is a constant, we can fold the cast into the constant.
|
|
|
|
if (Op1->getType() != Op0->getType())
|
|
|
|
if (Constant *Op1C = dyn_cast<Constant>(Op1)) {
|
|
|
|
Op1 = ConstantExpr::getCast(Op1C, Op0->getType());
|
|
|
|
} else {
|
|
|
|
// Otherwise, cast the RHS right before the setcc
|
|
|
|
Op1 = new CastInst(Op1, Op0->getType(), Op1->getName());
|
|
|
|
InsertNewInstBefore(cast<Instruction>(Op1), I);
|
|
|
|
}
|
|
|
|
return BinaryOperator::create(I.getOpcode(), Op0, Op1);
|
|
|
|
}
|
|
|
|
|
2003-11-03 05:17:03 +00:00
|
|
|
// Handle the special case of: setcc (cast bool to X), <cst>
|
|
|
|
// This comes up when you have code like
|
|
|
|
// int X = A < B;
|
|
|
|
// if (X) ...
|
|
|
|
// For generality, we handle any zero-extension of any operand comparison
|
|
|
|
// with a constant.
|
|
|
|
if (ConstantInt *ConstantRHS = dyn_cast<ConstantInt>(Op1)) {
|
|
|
|
const Type *SrcTy = CastOp0->getType();
|
|
|
|
const Type *DestTy = Op0->getType();
|
|
|
|
if (SrcTy->getPrimitiveSize() < DestTy->getPrimitiveSize() &&
|
|
|
|
(SrcTy->isUnsigned() || SrcTy == Type::BoolTy)) {
|
|
|
|
// Ok, we have an expansion of operand 0 into a new type. Get the
|
|
|
|
// constant value, masink off bits which are not set in the RHS. These
|
|
|
|
// could be set if the destination value is signed.
|
|
|
|
uint64_t ConstVal = ConstantRHS->getRawValue();
|
|
|
|
ConstVal &= (1ULL << DestTy->getPrimitiveSize()*8)-1;
|
|
|
|
|
|
|
|
// If the constant we are comparing it with has high bits set, which
|
|
|
|
// don't exist in the original value, the values could never be equal,
|
|
|
|
// because the source would be zero extended.
|
|
|
|
unsigned SrcBits =
|
|
|
|
SrcTy == Type::BoolTy ? 1 : SrcTy->getPrimitiveSize()*8;
|
2003-11-05 17:31:36 +00:00
|
|
|
bool HasSignBit = ConstVal & (1ULL << (DestTy->getPrimitiveSize()*8-1));
|
|
|
|
if (ConstVal & ~((1ULL << SrcBits)-1)) {
|
2003-11-03 05:17:03 +00:00
|
|
|
switch (I.getOpcode()) {
|
|
|
|
default: assert(0 && "Unknown comparison type!");
|
|
|
|
case Instruction::SetEQ:
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
case Instruction::SetNE:
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
case Instruction::SetLT:
|
|
|
|
case Instruction::SetLE:
|
|
|
|
if (DestTy->isSigned() && HasSignBit)
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
case Instruction::SetGT:
|
|
|
|
case Instruction::SetGE:
|
|
|
|
if (DestTy->isSigned() && HasSignBit)
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, we can replace the setcc with a setcc of the smaller
|
|
|
|
// operand value.
|
|
|
|
Op1 = ConstantExpr::getCast(cast<Constant>(Op1), SrcTy);
|
|
|
|
return BinaryOperator::create(I.getOpcode(), CastOp0, Op1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-06-25 16:13:24 +00:00
|
|
|
return Changed ? &I : 0;
|
2002-05-06 16:14:14 +00:00
|
|
|
}
|
|
|
|
|
2004-11-28 21:31:15 +00:00
|
|
|
// visitSetCondInstWithCastAndConstant - this method is part of the
|
|
|
|
// visitSetCondInst method. It handles the situation where we have:
|
|
|
|
// (setcc (cast X to larger), CI)
|
|
|
|
// It tries to remove the cast and even the setcc if the CI value
|
|
|
|
// and range of the cast allow it.
|
|
|
|
Instruction *
|
|
|
|
InstCombiner::visitSetCondInstWithCastAndConstant(BinaryOperator&I,
|
|
|
|
CastInst* LHSI,
|
|
|
|
ConstantInt* CI) {
|
|
|
|
const Type *SrcTy = LHSI->getOperand(0)->getType();
|
|
|
|
const Type *DestTy = LHSI->getType();
|
|
|
|
if (SrcTy->isIntegral() && DestTy->isIntegral()) {
|
|
|
|
unsigned SrcBits = SrcTy->getPrimitiveSize()*8;
|
|
|
|
unsigned DestBits = DestTy->getPrimitiveSize()*8;
|
|
|
|
if (SrcTy == Type::BoolTy)
|
|
|
|
SrcBits = 1;
|
|
|
|
if (DestTy == Type::BoolTy)
|
|
|
|
DestBits = 1;
|
|
|
|
if (SrcBits < DestBits) {
|
|
|
|
// There are fewer bits in the source of the cast than in the result
|
|
|
|
// of the cast. Any other case doesn't matter because the constant
|
|
|
|
// value won't have changed due to sign extension.
|
|
|
|
Constant *NewCst = ConstantExpr::getCast(CI, SrcTy);
|
|
|
|
if (ConstantExpr::getCast(NewCst, DestTy) == CI) {
|
|
|
|
// The constant value operand of the setCC before and after a
|
|
|
|
// cast to the source type of the cast instruction is the same
|
|
|
|
// value, so we just replace with the same setcc opcode, but
|
|
|
|
// using the source value compared to the constant casted to the
|
|
|
|
// source type.
|
|
|
|
if (SrcTy->isSigned() && DestTy->isUnsigned()) {
|
|
|
|
CastInst* Cst = new CastInst(LHSI->getOperand(0),
|
|
|
|
SrcTy->getUnsignedVersion(), LHSI->getName());
|
|
|
|
InsertNewInstBefore(Cst,I);
|
|
|
|
return new SetCondInst(I.getOpcode(), Cst,
|
|
|
|
ConstantExpr::getCast(CI, SrcTy->getUnsignedVersion()));
|
|
|
|
}
|
|
|
|
return new SetCondInst(I.getOpcode(), LHSI->getOperand(0),NewCst);
|
|
|
|
}
|
|
|
|
// The constant value before and after a cast to the source type
|
|
|
|
// is different, so various cases are possible depending on the
|
|
|
|
// opcode and the signs of the types involved in the cast.
|
|
|
|
switch (I.getOpcode()) {
|
|
|
|
case Instruction::SetLT: {
|
|
|
|
Constant* Max = ConstantIntegral::getMaxValue(SrcTy);
|
|
|
|
Max = ConstantExpr::getCast(Max, DestTy);
|
|
|
|
return ReplaceInstUsesWith(I, ConstantExpr::getSetLT(Max, CI));
|
|
|
|
}
|
|
|
|
case Instruction::SetGT: {
|
|
|
|
Constant* Min = ConstantIntegral::getMinValue(SrcTy);
|
|
|
|
Min = ConstantExpr::getCast(Min, DestTy);
|
|
|
|
return ReplaceInstUsesWith(I, ConstantExpr::getSetGT(Min, CI));
|
|
|
|
}
|
|
|
|
case Instruction::SetEQ:
|
|
|
|
// We're looking for equality, and we know the values are not
|
|
|
|
// equal so replace with constant False.
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
|
|
case Instruction::SetNE:
|
|
|
|
// We're testing for inequality, and we know the values are not
|
|
|
|
// equal so replace with constant True.
|
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
|
|
case Instruction::SetLE:
|
|
|
|
case Instruction::SetGE:
|
|
|
|
assert(!"SetLE and SetGE should be handled elsewhere");
|
|
|
|
default:
|
|
|
|
assert(!"unknown integer comparison");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2002-05-06 16:14:14 +00:00
|
|
|
|
|
|
|
|
2003-03-10 19:16:08 +00:00
|
|
|
Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
|
2002-06-25 16:13:24 +00:00
|
|
|
assert(I.getOperand(1)->getType() == Type::UByteTy);
|
|
|
|
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
2003-08-12 21:53:41 +00:00
|
|
|
bool isLeftShift = I.getOpcode() == Instruction::Shl;
|
2002-05-06 16:14:14 +00:00
|
|
|
|
|
|
|
// shl X, 0 == X and shr X, 0 == X
|
|
|
|
// shl 0, X == 0 and shr 0, X == 0
|
|
|
|
if (Op1 == Constant::getNullValue(Type::UByteTy) ||
|
2002-08-12 21:17:25 +00:00
|
|
|
Op0 == Constant::getNullValue(Op0->getType()))
|
|
|
|
return ReplaceInstUsesWith(I, Op0);
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(Op0)) { // undef >>s X -> undef
|
|
|
|
if (!isLeftShift && I.getType()->isSigned())
|
2004-10-16 23:28:04 +00:00
|
|
|
return ReplaceInstUsesWith(I, Op0);
|
2004-10-16 18:11:37 +00:00
|
|
|
else // undef << X -> 0 AND undef >>u X -> 0
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
|
|
}
|
|
|
|
if (isa<UndefValue>(Op1)) {
|
|
|
|
if (isLeftShift || I.getType()->isUnsigned())
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
|
|
else
|
|
|
|
return ReplaceInstUsesWith(I, Op0); // X >>s undef -> X
|
|
|
|
}
|
|
|
|
|
2003-08-12 21:53:41 +00:00
|
|
|
// shr int -1, X = -1 (for any arithmetic shift rights of ~0)
|
|
|
|
if (!isLeftShift)
|
|
|
|
if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0))
|
|
|
|
if (CSI->isAllOnesValue())
|
|
|
|
return ReplaceInstUsesWith(I, CSI);
|
|
|
|
|
2004-04-09 19:05:30 +00:00
|
|
|
// Try to fold constant and into select arguments.
|
|
|
|
if (isa<Constant>(Op0))
|
|
|
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
|
|
|
|
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
|
|
|
|
return R;
|
|
|
|
|
2002-05-06 16:14:14 +00:00
|
|
|
if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) {
|
2003-07-24 17:52:58 +00:00
|
|
|
// shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
|
|
|
|
// of a signed value.
|
|
|
|
//
|
2003-03-10 19:16:08 +00:00
|
|
|
unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
|
2004-02-23 20:30:06 +00:00
|
|
|
if (CUI->getValue() >= TypeBits) {
|
|
|
|
if (!Op0->getType()->isSigned() || isLeftShift)
|
|
|
|
return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
|
|
|
|
else {
|
|
|
|
I.setOperand(1, ConstantUInt::get(Type::UByteTy, TypeBits-1));
|
|
|
|
return &I;
|
|
|
|
}
|
|
|
|
}
|
2002-09-10 23:04:09 +00:00
|
|
|
|
2003-08-13 04:18:28 +00:00
|
|
|
// ((X*C1) << C2) == (X * (C1 << C2))
|
|
|
|
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0))
|
|
|
|
if (BO->getOpcode() == Instruction::Mul && isLeftShift)
|
|
|
|
if (Constant *BOOp = dyn_cast<Constant>(BO->getOperand(1)))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createMul(BO->getOperand(0),
|
|
|
|
ConstantExpr::getShl(BOOp, CUI));
|
2003-08-13 04:18:28 +00:00
|
|
|
|
2004-04-09 19:05:30 +00:00
|
|
|
// Try to fold constant and into select arguments.
|
|
|
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
|
|
|
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
|
|
|
|
return R;
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
if (isa<PHINode>(Op0))
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
|
|
return NV;
|
2003-08-13 04:18:28 +00:00
|
|
|
|
2003-08-12 21:53:41 +00:00
|
|
|
// If the operand is an bitwise operator with a constant RHS, and the
|
|
|
|
// shift is the only use, we can pull it out of the shift.
|
2003-10-15 16:48:29 +00:00
|
|
|
if (Op0->hasOneUse())
|
2003-08-12 21:53:41 +00:00
|
|
|
if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0))
|
|
|
|
if (ConstantInt *Op0C = dyn_cast<ConstantInt>(Op0BO->getOperand(1))) {
|
|
|
|
bool isValid = true; // Valid only for And, Or, Xor
|
|
|
|
bool highBitSet = false; // Transform if high bit of constant set?
|
|
|
|
|
|
|
|
switch (Op0BO->getOpcode()) {
|
|
|
|
default: isValid = false; break; // Do not perform transform!
|
2004-10-08 03:46:20 +00:00
|
|
|
case Instruction::Add:
|
|
|
|
isValid = isLeftShift;
|
|
|
|
break;
|
2003-08-12 21:53:41 +00:00
|
|
|
case Instruction::Or:
|
|
|
|
case Instruction::Xor:
|
|
|
|
highBitSet = false;
|
|
|
|
break;
|
|
|
|
case Instruction::And:
|
|
|
|
highBitSet = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this is a signed shift right, and the high bit is modified
|
|
|
|
// by the logical operation, do not perform the transformation.
|
|
|
|
// The highBitSet boolean indicates the value of the high bit of
|
|
|
|
// the constant which would cause it to be modified for this
|
|
|
|
// operation.
|
|
|
|
//
|
|
|
|
if (isValid && !isLeftShift && !I.getType()->isUnsigned()) {
|
|
|
|
uint64_t Val = Op0C->getRawValue();
|
|
|
|
isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isValid) {
|
2004-01-12 19:35:11 +00:00
|
|
|
Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, CUI);
|
2003-08-12 21:53:41 +00:00
|
|
|
|
|
|
|
Instruction *NewShift =
|
|
|
|
new ShiftInst(I.getOpcode(), Op0BO->getOperand(0), CUI,
|
|
|
|
Op0BO->getName());
|
|
|
|
Op0BO->setName("");
|
|
|
|
InsertNewInstBefore(NewShift, I);
|
|
|
|
|
|
|
|
return BinaryOperator::create(Op0BO->getOpcode(), NewShift,
|
|
|
|
NewRHS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-07-24 17:52:58 +00:00
|
|
|
// If this is a shift of a shift, see if we can fold the two together...
|
2003-08-12 21:53:41 +00:00
|
|
|
if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0))
|
2003-07-24 18:38:56 +00:00
|
|
|
if (ConstantUInt *ShiftAmt1C =
|
|
|
|
dyn_cast<ConstantUInt>(Op0SI->getOperand(1))) {
|
2003-07-24 17:52:58 +00:00
|
|
|
unsigned ShiftAmt1 = ShiftAmt1C->getValue();
|
|
|
|
unsigned ShiftAmt2 = CUI->getValue();
|
|
|
|
|
|
|
|
// Check for (A << c1) << c2 and (A >> c1) >> c2
|
|
|
|
if (I.getOpcode() == Op0SI->getOpcode()) {
|
|
|
|
unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift...
|
2004-02-23 20:30:06 +00:00
|
|
|
if (Op0->getType()->getPrimitiveSize()*8 < Amt)
|
|
|
|
Amt = Op0->getType()->getPrimitiveSize()*8;
|
2003-07-24 17:52:58 +00:00
|
|
|
return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0),
|
|
|
|
ConstantUInt::get(Type::UByteTy, Amt));
|
|
|
|
}
|
|
|
|
|
2003-07-24 18:38:56 +00:00
|
|
|
// Check for (A << c1) >> c2 or visaversa. If we are dealing with
|
|
|
|
// signed types, we can only support the (A >> c1) << c2 configuration,
|
|
|
|
// because it can not turn an arbitrary bit of A into a sign bit.
|
2003-08-12 21:53:41 +00:00
|
|
|
if (I.getType()->isUnsigned() || isLeftShift) {
|
2003-07-24 17:52:58 +00:00
|
|
|
// Calculate bitmask for what gets shifted off the edge...
|
|
|
|
Constant *C = ConstantIntegral::getAllOnesValue(I.getType());
|
2003-08-12 21:53:41 +00:00
|
|
|
if (isLeftShift)
|
2004-06-10 02:07:29 +00:00
|
|
|
C = ConstantExpr::getShl(C, ShiftAmt1C);
|
2003-08-12 21:53:41 +00:00
|
|
|
else
|
2004-06-10 02:07:29 +00:00
|
|
|
C = ConstantExpr::getShr(C, ShiftAmt1C);
|
2003-07-24 17:52:58 +00:00
|
|
|
|
|
|
|
Instruction *Mask =
|
2004-06-10 02:07:29 +00:00
|
|
|
BinaryOperator::createAnd(Op0SI->getOperand(0), C,
|
|
|
|
Op0SI->getOperand(0)->getName()+".mask");
|
2003-07-24 17:52:58 +00:00
|
|
|
InsertNewInstBefore(Mask, I);
|
|
|
|
|
|
|
|
// Figure out what flavor of shift we should use...
|
|
|
|
if (ShiftAmt1 == ShiftAmt2)
|
|
|
|
return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2
|
|
|
|
else if (ShiftAmt1 < ShiftAmt2) {
|
|
|
|
return new ShiftInst(I.getOpcode(), Mask,
|
|
|
|
ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1));
|
|
|
|
} else {
|
|
|
|
return new ShiftInst(Op0SI->getOpcode(), Mask,
|
|
|
|
ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-05-06 16:14:14 +00:00
|
|
|
}
|
2002-10-08 16:16:40 +00:00
|
|
|
|
2002-05-06 16:14:14 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-07-20 00:59:32 +00:00
|
|
|
enum CastType {
|
|
|
|
Noop = 0,
|
|
|
|
Truncate = 1,
|
|
|
|
Signext = 2,
|
|
|
|
Zeroext = 3
|
|
|
|
};
|
|
|
|
|
|
|
|
/// getCastType - In the future, we will split the cast instruction into these
|
|
|
|
/// various types. Until then, we have to do the analysis here.
|
|
|
|
static CastType getCastType(const Type *Src, const Type *Dest) {
|
|
|
|
assert(Src->isIntegral() && Dest->isIntegral() &&
|
|
|
|
"Only works on integral types!");
|
|
|
|
unsigned SrcSize = Src->getPrimitiveSize()*8;
|
|
|
|
if (Src == Type::BoolTy) SrcSize = 1;
|
|
|
|
unsigned DestSize = Dest->getPrimitiveSize()*8;
|
|
|
|
if (Dest == Type::BoolTy) DestSize = 1;
|
|
|
|
|
|
|
|
if (SrcSize == DestSize) return Noop;
|
|
|
|
if (SrcSize > DestSize) return Truncate;
|
|
|
|
if (Src->isSigned()) return Signext;
|
|
|
|
return Zeroext;
|
|
|
|
}
|
|
|
|
|
2002-05-06 16:14:14 +00:00
|
|
|
|
2002-05-02 17:06:02 +00:00
|
|
|
// isEliminableCastOfCast - Return true if it is valid to eliminate the CI
|
|
|
|
// instruction.
|
|
|
|
//
|
2003-07-24 17:35:25 +00:00
|
|
|
static inline bool isEliminableCastOfCast(const Type *SrcTy, const Type *MidTy,
|
2004-07-20 05:21:00 +00:00
|
|
|
const Type *DstTy, TargetData *TD) {
|
2002-05-02 17:06:02 +00:00
|
|
|
|
2002-08-02 20:00:25 +00:00
|
|
|
// It is legal to eliminate the instruction if casting A->B->A if the sizes
|
|
|
|
// are identical and the bits don't get reinterpreted (for example
|
2004-07-21 19:50:44 +00:00
|
|
|
// int->float->int would not be allowed).
|
2003-05-20 18:45:36 +00:00
|
|
|
if (SrcTy == DstTy && SrcTy->isLosslesslyConvertibleTo(MidTy))
|
2002-08-02 20:00:25 +00:00
|
|
|
return true;
|
2002-05-02 17:06:02 +00:00
|
|
|
|
2004-07-21 04:27:24 +00:00
|
|
|
// If we are casting between pointer and integer types, treat pointers as
|
|
|
|
// integers of the appropriate size for the code below.
|
|
|
|
if (isa<PointerType>(SrcTy)) SrcTy = TD->getIntPtrType();
|
|
|
|
if (isa<PointerType>(MidTy)) MidTy = TD->getIntPtrType();
|
|
|
|
if (isa<PointerType>(DstTy)) DstTy = TD->getIntPtrType();
|
2004-07-20 05:21:00 +00:00
|
|
|
|
2002-05-02 17:06:02 +00:00
|
|
|
// Allow free casting and conversion of sizes as long as the sign doesn't
|
|
|
|
// change...
|
2002-09-03 01:08:28 +00:00
|
|
|
if (SrcTy->isIntegral() && MidTy->isIntegral() && DstTy->isIntegral()) {
|
2004-07-20 00:59:32 +00:00
|
|
|
CastType FirstCast = getCastType(SrcTy, MidTy);
|
|
|
|
CastType SecondCast = getCastType(MidTy, DstTy);
|
|
|
|
|
|
|
|
// Capture the effect of these two casts. If the result is a legal cast,
|
|
|
|
// the CastType is stored here, otherwise a special code is used.
|
|
|
|
static const unsigned CastResult[] = {
|
|
|
|
// First cast is noop
|
|
|
|
0, 1, 2, 3,
|
|
|
|
// First cast is a truncate
|
|
|
|
1, 1, 4, 4, // trunc->extend is not safe to eliminate
|
|
|
|
// First cast is a sign ext
|
2004-07-21 19:50:44 +00:00
|
|
|
2, 5, 2, 4, // signext->zeroext never ok
|
2004-07-20 00:59:32 +00:00
|
|
|
// First cast is a zero ext
|
2004-07-21 19:50:44 +00:00
|
|
|
3, 5, 3, 3,
|
2004-07-20 00:59:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
unsigned Result = CastResult[FirstCast*4+SecondCast];
|
|
|
|
switch (Result) {
|
|
|
|
default: assert(0 && "Illegal table value!");
|
|
|
|
case 0:
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
// FIXME: in the future, when LLVM has explicit sign/zeroextends and
|
|
|
|
// truncates, we could eliminate more casts.
|
|
|
|
return (unsigned)getCastType(SrcTy, DstTy) == Result;
|
|
|
|
case 4:
|
|
|
|
return false; // Not possible to eliminate this here.
|
|
|
|
case 5:
|
2004-07-21 19:50:44 +00:00
|
|
|
// Sign or zero extend followed by truncate is always ok if the result
|
|
|
|
// is a truncate or noop.
|
|
|
|
CastType ResultCast = getCastType(SrcTy, DstTy);
|
|
|
|
if (ResultCast == Noop || ResultCast == Truncate)
|
|
|
|
return true;
|
|
|
|
// Otherwise we are still growing the value, we are only safe if the
|
|
|
|
// result will match the sign/zeroextendness of the result.
|
|
|
|
return ResultCast == FirstCast;
|
2002-08-15 16:15:25 +00:00
|
|
|
}
|
2002-08-02 20:00:25 +00:00
|
|
|
}
|
2002-05-02 17:06:02 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2004-07-20 05:21:00 +00:00
|
|
|
static bool ValueRequiresCast(const Value *V, const Type *Ty, TargetData *TD) {
|
2003-07-24 17:35:25 +00:00
|
|
|
if (V->getType() == Ty || isa<Constant>(V)) return false;
|
|
|
|
if (const CastInst *CI = dyn_cast<CastInst>(V))
|
2004-07-20 05:21:00 +00:00
|
|
|
if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty,
|
|
|
|
TD))
|
2003-07-24 17:35:25 +00:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// InsertOperandCastBefore - This inserts a cast of V to DestTy before the
|
|
|
|
/// InsertBefore instruction. This is specialized a bit to avoid inserting
|
|
|
|
/// casts that are known to not do anything...
|
|
|
|
///
|
|
|
|
Value *InstCombiner::InsertOperandCastBefore(Value *V, const Type *DestTy,
|
|
|
|
Instruction *InsertBefore) {
|
|
|
|
if (V->getType() == DestTy) return V;
|
|
|
|
if (Constant *C = dyn_cast<Constant>(V))
|
|
|
|
return ConstantExpr::getCast(C, DestTy);
|
|
|
|
|
|
|
|
CastInst *CI = new CastInst(V, DestTy, V->getName());
|
|
|
|
InsertNewInstBefore(CI, *InsertBefore);
|
|
|
|
return CI;
|
|
|
|
}
|
2002-05-02 17:06:02 +00:00
|
|
|
|
|
|
|
// CastInst simplification
|
2002-04-18 17:39:14 +00:00
|
|
|
//
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitCastInst(CastInst &CI) {
|
2003-06-23 21:59:52 +00:00
|
|
|
Value *Src = CI.getOperand(0);
|
|
|
|
|
2002-05-02 17:06:02 +00:00
|
|
|
// If the user is casting a value to the same type, eliminate this cast
|
|
|
|
// instruction...
|
2003-06-23 21:59:52 +00:00
|
|
|
if (CI.getType() == Src->getType())
|
|
|
|
return ReplaceInstUsesWith(CI, Src);
|
2002-05-02 17:06:02 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(Src)) // cast undef -> undef
|
|
|
|
return ReplaceInstUsesWith(CI, UndefValue::get(CI.getType()));
|
|
|
|
|
2002-05-02 17:06:02 +00:00
|
|
|
// If casting the result of another cast instruction, try to eliminate this
|
|
|
|
// one!
|
|
|
|
//
|
2003-06-23 21:59:52 +00:00
|
|
|
if (CastInst *CSrc = dyn_cast<CastInst>(Src)) {
|
2003-07-24 17:35:25 +00:00
|
|
|
if (isEliminableCastOfCast(CSrc->getOperand(0)->getType(),
|
2004-07-20 05:21:00 +00:00
|
|
|
CSrc->getType(), CI.getType(), TD)) {
|
2002-05-02 17:06:02 +00:00
|
|
|
// This instruction now refers directly to the cast's src operand. This
|
|
|
|
// has a good chance of making CSrc dead.
|
2002-06-25 16:13:24 +00:00
|
|
|
CI.setOperand(0, CSrc->getOperand(0));
|
|
|
|
return &CI;
|
2002-05-02 17:06:02 +00:00
|
|
|
}
|
|
|
|
|
2002-08-02 20:00:25 +00:00
|
|
|
// If this is an A->B->A cast, and we are dealing with integral types, try
|
|
|
|
// to convert this into a logical 'and' instruction.
|
|
|
|
//
|
|
|
|
if (CSrc->getOperand(0)->getType() == CI.getType() &&
|
2002-09-03 01:08:28 +00:00
|
|
|
CI.getType()->isInteger() && CSrc->getType()->isInteger() &&
|
2002-08-02 20:00:25 +00:00
|
|
|
CI.getType()->isUnsigned() && CSrc->getType()->isUnsigned() &&
|
|
|
|
CSrc->getType()->getPrimitiveSize() < CI.getType()->getPrimitiveSize()){
|
|
|
|
assert(CSrc->getType() != Type::ULongTy &&
|
|
|
|
"Cannot have type bigger than ulong!");
|
2003-05-26 23:41:32 +00:00
|
|
|
uint64_t AndValue = (1ULL << CSrc->getType()->getPrimitiveSize()*8)-1;
|
2002-08-02 20:00:25 +00:00
|
|
|
Constant *AndOp = ConstantUInt::get(CI.getType(), AndValue);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(CSrc->getOperand(0), AndOp);
|
2002-08-02 20:00:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-05-25 04:29:21 +00:00
|
|
|
// If this is a cast to bool, turn it into the appropriate setne instruction.
|
|
|
|
if (CI.getType() == Type::BoolTy)
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetNE(CI.getOperand(0),
|
2004-05-25 04:29:21 +00:00
|
|
|
Constant::getNullValue(CI.getOperand(0)->getType()));
|
|
|
|
|
2003-06-21 23:12:02 +00:00
|
|
|
// If casting the result of a getelementptr instruction with no offset, turn
|
|
|
|
// this into a cast of the original pointer!
|
|
|
|
//
|
2003-06-23 21:59:52 +00:00
|
|
|
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Src)) {
|
2003-06-21 23:12:02 +00:00
|
|
|
bool AllZeroOperands = true;
|
|
|
|
for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
|
|
|
|
if (!isa<Constant>(GEP->getOperand(i)) ||
|
|
|
|
!cast<Constant>(GEP->getOperand(i))->isNullValue()) {
|
|
|
|
AllZeroOperands = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (AllZeroOperands) {
|
|
|
|
CI.setOperand(0, GEP->getOperand(0));
|
|
|
|
return &CI;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-02 05:57:39 +00:00
|
|
|
// If we are casting a malloc or alloca to a pointer to a type of the same
|
|
|
|
// size, rewrite the allocation instruction to allocate the "right" type.
|
|
|
|
//
|
|
|
|
if (AllocationInst *AI = dyn_cast<AllocationInst>(Src))
|
2003-11-02 06:54:48 +00:00
|
|
|
if (AI->hasOneUse() && !AI->isArrayAllocation())
|
2003-11-02 05:57:39 +00:00
|
|
|
if (const PointerType *PTy = dyn_cast<PointerType>(CI.getType())) {
|
|
|
|
// Get the type really allocated and the type casted to...
|
|
|
|
const Type *AllocElTy = AI->getAllocatedType();
|
|
|
|
const Type *CastElTy = PTy->getElementType();
|
2004-07-06 19:28:42 +00:00
|
|
|
if (AllocElTy->isSized() && CastElTy->isSized()) {
|
|
|
|
unsigned AllocElTySize = TD->getTypeSize(AllocElTy);
|
|
|
|
unsigned CastElTySize = TD->getTypeSize(CastElTy);
|
2003-11-05 17:31:36 +00:00
|
|
|
|
2004-07-06 19:28:42 +00:00
|
|
|
// If the allocation is for an even multiple of the cast type size
|
|
|
|
if (CastElTySize && (AllocElTySize % CastElTySize == 0)) {
|
|
|
|
Value *Amt = ConstantUInt::get(Type::UIntTy,
|
2003-11-02 05:57:39 +00:00
|
|
|
AllocElTySize/CastElTySize);
|
2004-07-06 19:28:42 +00:00
|
|
|
std::string Name = AI->getName(); AI->setName("");
|
|
|
|
AllocationInst *New;
|
|
|
|
if (isa<MallocInst>(AI))
|
|
|
|
New = new MallocInst(CastElTy, Amt, Name);
|
|
|
|
else
|
|
|
|
New = new AllocaInst(CastElTy, Amt, Name);
|
|
|
|
InsertNewInstBefore(New, *AI);
|
|
|
|
return ReplaceInstUsesWith(CI, New);
|
|
|
|
}
|
2003-11-02 05:57:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Fold binary expressions and casts into PHI nodes that have all constant inputs.
This takes something like this:
%A = phi int [ 3, %cond_false.0 ], [ 2, %endif.0.i ], [ 2, %endif.1.i ]
%B = div int %tmp.243, 4
and turns it into:
%A = phi int [ 3/4, %cond_false.0 ], [ 2/4, %endif.0.i ], [ 2/4, %endif.1.i ]
which is later simplified (in this case) into %A = 0.
This triggers thousands of times in spec, for example, 269 times in 176.gcc.
This is tested by InstCombine/add.ll:test23 and set.ll:test18.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16582 91177308-0d34-0410-b5e6-96231b3b80d8
2004-09-29 05:07:12 +00:00
|
|
|
if (isa<PHINode>(Src))
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(CI))
|
|
|
|
return NV;
|
|
|
|
|
2003-07-24 17:35:25 +00:00
|
|
|
// If the source value is an instruction with only this use, we can attempt to
|
|
|
|
// propagate the cast into the instruction. Also, only handle integral types
|
|
|
|
// for now.
|
|
|
|
if (Instruction *SrcI = dyn_cast<Instruction>(Src))
|
2003-10-15 16:48:29 +00:00
|
|
|
if (SrcI->hasOneUse() && Src->getType()->isIntegral() &&
|
2003-07-24 17:35:25 +00:00
|
|
|
CI.getType()->isInteger()) { // Don't mess with casts to bool here
|
|
|
|
const Type *DestTy = CI.getType();
|
|
|
|
unsigned SrcBitSize = getTypeSizeInBits(Src->getType());
|
|
|
|
unsigned DestBitSize = getTypeSizeInBits(DestTy);
|
|
|
|
|
|
|
|
Value *Op0 = SrcI->getNumOperands() > 0 ? SrcI->getOperand(0) : 0;
|
|
|
|
Value *Op1 = SrcI->getNumOperands() > 1 ? SrcI->getOperand(1) : 0;
|
|
|
|
|
|
|
|
switch (SrcI->getOpcode()) {
|
|
|
|
case Instruction::Add:
|
|
|
|
case Instruction::Mul:
|
|
|
|
case Instruction::And:
|
|
|
|
case Instruction::Or:
|
|
|
|
case Instruction::Xor:
|
|
|
|
// If we are discarding information, or just changing the sign, rewrite.
|
|
|
|
if (DestBitSize <= SrcBitSize && DestBitSize != 1) {
|
|
|
|
// Don't insert two casts if they cannot be eliminated. We allow two
|
|
|
|
// casts to be inserted if the sizes are the same. This could only be
|
|
|
|
// converting signedness, which is a noop.
|
2004-07-20 05:21:00 +00:00
|
|
|
if (DestBitSize == SrcBitSize || !ValueRequiresCast(Op1, DestTy,TD) ||
|
|
|
|
!ValueRequiresCast(Op0, DestTy, TD)) {
|
2003-07-24 17:35:25 +00:00
|
|
|
Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI);
|
|
|
|
Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI);
|
|
|
|
return BinaryOperator::create(cast<BinaryOperator>(SrcI)
|
|
|
|
->getOpcode(), Op0c, Op1c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Instruction::Shl:
|
|
|
|
// Allow changing the sign of the source operand. Do not allow changing
|
|
|
|
// the size of the shift, UNLESS the shift amount is a constant. We
|
|
|
|
// mush not change variable sized shifts to a smaller size, because it
|
|
|
|
// is undefined to shift more bits out than exist in the value.
|
|
|
|
if (DestBitSize == SrcBitSize ||
|
|
|
|
(DestBitSize < SrcBitSize && isa<Constant>(Op1))) {
|
|
|
|
Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI);
|
|
|
|
return new ShiftInst(Instruction::Shl, Op0c, Op1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-04-18 17:39:14 +00:00
|
|
|
return 0;
|
2001-12-14 16:52:21 +00:00
|
|
|
}
|
|
|
|
|
Implement select.ll:test12*
This transforms code like this:
%C = or %A, %B
%D = select %cond, %C, %A
into:
%C = select %cond, %B, 0
%D = or %A, %C
Since B is often a constant, the select can often be eliminated. In any case,
this reduces the usage count of A, allowing subsequent optimizations to happen.
This xform applies when the operator is any of:
add, sub, mul, or, xor, and, shl, shr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12800 91177308-0d34-0410-b5e6-96231b3b80d8
2004-04-09 23:46:01 +00:00
|
|
|
/// GetSelectFoldableOperands - We want to turn code that looks like this:
|
|
|
|
/// %C = or %A, %B
|
|
|
|
/// %D = select %cond, %C, %A
|
|
|
|
/// into:
|
|
|
|
/// %C = select %cond, %B, 0
|
|
|
|
/// %D = or %A, %C
|
|
|
|
///
|
|
|
|
/// Assuming that the specified instruction is an operand to the select, return
|
|
|
|
/// a bitmask indicating which operands of this instruction are foldable if they
|
|
|
|
/// equal the other incoming value of the select.
|
|
|
|
///
|
|
|
|
static unsigned GetSelectFoldableOperands(Instruction *I) {
|
|
|
|
switch (I->getOpcode()) {
|
|
|
|
case Instruction::Add:
|
|
|
|
case Instruction::Mul:
|
|
|
|
case Instruction::And:
|
|
|
|
case Instruction::Or:
|
|
|
|
case Instruction::Xor:
|
|
|
|
return 3; // Can fold through either operand.
|
|
|
|
case Instruction::Sub: // Can only fold on the amount subtracted.
|
|
|
|
case Instruction::Shl: // Can only fold on the shift amount.
|
|
|
|
case Instruction::Shr:
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
return 0; // Cannot fold
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GetSelectFoldableConstant - For the same transformation as the previous
|
|
|
|
/// function, return the identity constant that goes into the select.
|
|
|
|
static Constant *GetSelectFoldableConstant(Instruction *I) {
|
|
|
|
switch (I->getOpcode()) {
|
|
|
|
default: assert(0 && "This cannot happen!"); abort();
|
|
|
|
case Instruction::Add:
|
|
|
|
case Instruction::Sub:
|
|
|
|
case Instruction::Or:
|
|
|
|
case Instruction::Xor:
|
|
|
|
return Constant::getNullValue(I->getType());
|
|
|
|
case Instruction::Shl:
|
|
|
|
case Instruction::Shr:
|
|
|
|
return Constant::getNullValue(Type::UByteTy);
|
|
|
|
case Instruction::And:
|
|
|
|
return ConstantInt::getAllOnesValue(I->getType());
|
|
|
|
case Instruction::Mul:
|
|
|
|
return ConstantInt::get(I->getType(), 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-12 05:52:32 +00:00
|
|
|
Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
|
2004-03-30 19:37:13 +00:00
|
|
|
Value *CondVal = SI.getCondition();
|
|
|
|
Value *TrueVal = SI.getTrueValue();
|
|
|
|
Value *FalseVal = SI.getFalseValue();
|
|
|
|
|
|
|
|
// select true, X, Y -> X
|
|
|
|
// select false, X, Y -> Y
|
|
|
|
if (ConstantBool *C = dyn_cast<ConstantBool>(CondVal))
|
2004-03-12 05:52:32 +00:00
|
|
|
if (C == ConstantBool::True)
|
2004-03-30 19:37:13 +00:00
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
2004-03-12 05:52:32 +00:00
|
|
|
else {
|
|
|
|
assert(C == ConstantBool::False);
|
2004-03-30 19:37:13 +00:00
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
// select C, X, X -> X
|
|
|
|
if (TrueVal == FalseVal)
|
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(TrueVal)) // select C, undef, X -> X
|
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
|
|
|
if (isa<UndefValue>(FalseVal)) // select C, X, undef -> X
|
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
|
|
|
if (isa<UndefValue>(CondVal)) { // select undef, X, Y -> X or Y
|
|
|
|
if (isa<Constant>(TrueVal))
|
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
|
|
|
else
|
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
|
|
|
}
|
|
|
|
|
2004-04-08 04:43:23 +00:00
|
|
|
if (SI.getType() == Type::BoolTy)
|
|
|
|
if (ConstantBool *C = dyn_cast<ConstantBool>(TrueVal)) {
|
|
|
|
if (C == ConstantBool::True) {
|
|
|
|
// Change: A = select B, true, C --> A = or B, C
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createOr(CondVal, FalseVal);
|
2004-04-08 04:43:23 +00:00
|
|
|
} else {
|
|
|
|
// Change: A = select B, false, C --> A = and !B, C
|
|
|
|
Value *NotCond =
|
|
|
|
InsertNewInstBefore(BinaryOperator::createNot(CondVal,
|
|
|
|
"not."+CondVal->getName()), SI);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(NotCond, FalseVal);
|
2004-04-08 04:43:23 +00:00
|
|
|
}
|
|
|
|
} else if (ConstantBool *C = dyn_cast<ConstantBool>(FalseVal)) {
|
|
|
|
if (C == ConstantBool::False) {
|
|
|
|
// Change: A = select B, C, false --> A = and B, C
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(CondVal, TrueVal);
|
2004-04-08 04:43:23 +00:00
|
|
|
} else {
|
|
|
|
// Change: A = select B, C, true --> A = or !B, C
|
|
|
|
Value *NotCond =
|
|
|
|
InsertNewInstBefore(BinaryOperator::createNot(CondVal,
|
|
|
|
"not."+CondVal->getName()), SI);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createOr(NotCond, TrueVal);
|
2004-04-08 04:43:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-04-09 19:05:30 +00:00
|
|
|
// Selecting between two integer constants?
|
|
|
|
if (ConstantInt *TrueValC = dyn_cast<ConstantInt>(TrueVal))
|
|
|
|
if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal)) {
|
|
|
|
// select C, 1, 0 -> cast C to int
|
|
|
|
if (FalseValC->isNullValue() && TrueValC->getRawValue() == 1) {
|
|
|
|
return new CastInst(CondVal, SI.getType());
|
|
|
|
} else if (TrueValC->isNullValue() && FalseValC->getRawValue() == 1) {
|
|
|
|
// select C, 0, 1 -> cast !C to int
|
|
|
|
Value *NotCond =
|
|
|
|
InsertNewInstBefore(BinaryOperator::createNot(CondVal,
|
2004-04-09 18:19:44 +00:00
|
|
|
"not."+CondVal->getName()), SI);
|
2004-04-09 19:05:30 +00:00
|
|
|
return new CastInst(NotCond, SI.getType());
|
2004-04-09 18:19:44 +00:00
|
|
|
}
|
2004-06-09 07:59:58 +00:00
|
|
|
|
|
|
|
// If one of the constants is zero (we know they can't both be) and we
|
|
|
|
// have a setcc instruction with zero, and we have an 'and' with the
|
|
|
|
// non-constant value, eliminate this whole mess. This corresponds to
|
|
|
|
// cases like this: ((X & 27) ? 27 : 0)
|
|
|
|
if (TrueValC->isNullValue() || FalseValC->isNullValue())
|
|
|
|
if (Instruction *IC = dyn_cast<Instruction>(SI.getCondition()))
|
|
|
|
if ((IC->getOpcode() == Instruction::SetEQ ||
|
|
|
|
IC->getOpcode() == Instruction::SetNE) &&
|
|
|
|
isa<ConstantInt>(IC->getOperand(1)) &&
|
|
|
|
cast<Constant>(IC->getOperand(1))->isNullValue())
|
|
|
|
if (Instruction *ICA = dyn_cast<Instruction>(IC->getOperand(0)))
|
|
|
|
if (ICA->getOpcode() == Instruction::And &&
|
|
|
|
isa<ConstantInt>(ICA->getOperand(1)) &&
|
|
|
|
(ICA->getOperand(1) == TrueValC ||
|
|
|
|
ICA->getOperand(1) == FalseValC) &&
|
|
|
|
isOneBitSet(cast<ConstantInt>(ICA->getOperand(1)))) {
|
|
|
|
// Okay, now we know that everything is set up, we just don't
|
|
|
|
// know whether we have a setne or seteq and whether the true or
|
|
|
|
// false val is the zero.
|
|
|
|
bool ShouldNotVal = !TrueValC->isNullValue();
|
|
|
|
ShouldNotVal ^= IC->getOpcode() == Instruction::SetNE;
|
|
|
|
Value *V = ICA;
|
|
|
|
if (ShouldNotVal)
|
|
|
|
V = InsertNewInstBefore(BinaryOperator::create(
|
|
|
|
Instruction::Xor, V, ICA->getOperand(1)), SI);
|
|
|
|
return ReplaceInstUsesWith(SI, V);
|
|
|
|
}
|
2004-03-12 05:52:32 +00:00
|
|
|
}
|
2004-04-10 22:21:27 +00:00
|
|
|
|
|
|
|
// See if we are selecting two values based on a comparison of the two values.
|
|
|
|
if (SetCondInst *SCI = dyn_cast<SetCondInst>(CondVal)) {
|
|
|
|
if (SCI->getOperand(0) == TrueVal && SCI->getOperand(1) == FalseVal) {
|
|
|
|
// Transform (X == Y) ? X : Y -> Y
|
|
|
|
if (SCI->getOpcode() == Instruction::SetEQ)
|
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
|
|
|
// Transform (X != Y) ? X : Y -> X
|
|
|
|
if (SCI->getOpcode() == Instruction::SetNE)
|
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
|
|
|
// NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc.
|
|
|
|
|
|
|
|
} else if (SCI->getOperand(0) == FalseVal && SCI->getOperand(1) == TrueVal){
|
|
|
|
// Transform (X == Y) ? Y : X -> X
|
|
|
|
if (SCI->getOpcode() == Instruction::SetEQ)
|
2004-04-11 01:39:19 +00:00
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
2004-04-10 22:21:27 +00:00
|
|
|
// Transform (X != Y) ? Y : X -> Y
|
|
|
|
if (SCI->getOpcode() == Instruction::SetNE)
|
2004-04-11 01:39:19 +00:00
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
2004-04-10 22:21:27 +00:00
|
|
|
// NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc.
|
|
|
|
}
|
|
|
|
}
|
2004-04-08 04:43:23 +00:00
|
|
|
|
Implement select.ll:test12*
This transforms code like this:
%C = or %A, %B
%D = select %cond, %C, %A
into:
%C = select %cond, %B, 0
%D = or %A, %C
Since B is often a constant, the select can often be eliminated. In any case,
this reduces the usage count of A, allowing subsequent optimizations to happen.
This xform applies when the operator is any of:
add, sub, mul, or, xor, and, shl, shr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12800 91177308-0d34-0410-b5e6-96231b3b80d8
2004-04-09 23:46:01 +00:00
|
|
|
// See if we can fold the select into one of our operands.
|
|
|
|
if (SI.getType()->isInteger()) {
|
|
|
|
// See the comment above GetSelectFoldableOperands for a description of the
|
|
|
|
// transformation we are doing here.
|
|
|
|
if (Instruction *TVI = dyn_cast<Instruction>(TrueVal))
|
|
|
|
if (TVI->hasOneUse() && TVI->getNumOperands() == 2 &&
|
|
|
|
!isa<Constant>(FalseVal))
|
|
|
|
if (unsigned SFO = GetSelectFoldableOperands(TVI)) {
|
|
|
|
unsigned OpToFold = 0;
|
|
|
|
if ((SFO & 1) && FalseVal == TVI->getOperand(0)) {
|
|
|
|
OpToFold = 1;
|
|
|
|
} else if ((SFO & 2) && FalseVal == TVI->getOperand(1)) {
|
|
|
|
OpToFold = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OpToFold) {
|
|
|
|
Constant *C = GetSelectFoldableConstant(TVI);
|
|
|
|
std::string Name = TVI->getName(); TVI->setName("");
|
|
|
|
Instruction *NewSel =
|
|
|
|
new SelectInst(SI.getCondition(), TVI->getOperand(2-OpToFold), C,
|
|
|
|
Name);
|
|
|
|
InsertNewInstBefore(NewSel, SI);
|
|
|
|
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(TVI))
|
|
|
|
return BinaryOperator::create(BO->getOpcode(), FalseVal, NewSel);
|
|
|
|
else if (ShiftInst *SI = dyn_cast<ShiftInst>(TVI))
|
|
|
|
return new ShiftInst(SI->getOpcode(), FalseVal, NewSel);
|
|
|
|
else {
|
|
|
|
assert(0 && "Unknown instruction!!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-09-29 17:40:11 +00:00
|
|
|
|
Implement select.ll:test12*
This transforms code like this:
%C = or %A, %B
%D = select %cond, %C, %A
into:
%C = select %cond, %B, 0
%D = or %A, %C
Since B is often a constant, the select can often be eliminated. In any case,
this reduces the usage count of A, allowing subsequent optimizations to happen.
This xform applies when the operator is any of:
add, sub, mul, or, xor, and, shl, shr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12800 91177308-0d34-0410-b5e6-96231b3b80d8
2004-04-09 23:46:01 +00:00
|
|
|
if (Instruction *FVI = dyn_cast<Instruction>(FalseVal))
|
|
|
|
if (FVI->hasOneUse() && FVI->getNumOperands() == 2 &&
|
|
|
|
!isa<Constant>(TrueVal))
|
|
|
|
if (unsigned SFO = GetSelectFoldableOperands(FVI)) {
|
|
|
|
unsigned OpToFold = 0;
|
|
|
|
if ((SFO & 1) && TrueVal == FVI->getOperand(0)) {
|
|
|
|
OpToFold = 1;
|
|
|
|
} else if ((SFO & 2) && TrueVal == FVI->getOperand(1)) {
|
|
|
|
OpToFold = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OpToFold) {
|
|
|
|
Constant *C = GetSelectFoldableConstant(FVI);
|
|
|
|
std::string Name = FVI->getName(); FVI->setName("");
|
|
|
|
Instruction *NewSel =
|
|
|
|
new SelectInst(SI.getCondition(), C, FVI->getOperand(2-OpToFold),
|
|
|
|
Name);
|
|
|
|
InsertNewInstBefore(NewSel, SI);
|
|
|
|
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(FVI))
|
|
|
|
return BinaryOperator::create(BO->getOpcode(), TrueVal, NewSel);
|
|
|
|
else if (ShiftInst *SI = dyn_cast<ShiftInst>(FVI))
|
|
|
|
return new ShiftInst(SI->getOpcode(), TrueVal, NewSel);
|
|
|
|
else {
|
|
|
|
assert(0 && "Unknown instruction!!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-03-12 05:52:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-06-19 17:00:31 +00:00
|
|
|
// CallInst simplification
|
|
|
|
//
|
|
|
|
Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
2004-02-28 05:22:00 +00:00
|
|
|
// Intrinsics cannot occur in an invoke, so handle them here instead of in
|
|
|
|
// visitCallSite.
|
2004-10-12 04:52:52 +00:00
|
|
|
if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&CI)) {
|
|
|
|
bool Changed = false;
|
|
|
|
|
|
|
|
// memmove/cpy/set of zero bytes is a noop.
|
|
|
|
if (Constant *NumBytes = dyn_cast<Constant>(MI->getLength())) {
|
|
|
|
if (NumBytes->isNullValue()) return EraseInstFromFunction(CI);
|
|
|
|
|
|
|
|
// FIXME: Increase alignment here.
|
|
|
|
|
|
|
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(NumBytes))
|
|
|
|
if (CI->getRawValue() == 1) {
|
|
|
|
// Replace the instruction with just byte operations. We would
|
|
|
|
// transform other cases to loads/stores, but we don't know if
|
|
|
|
// alignment is sufficient.
|
|
|
|
}
|
2004-02-28 05:22:00 +00:00
|
|
|
}
|
|
|
|
|
2004-10-12 04:52:52 +00:00
|
|
|
// If we have a memmove and the source operation is a constant global,
|
|
|
|
// then the source and dest pointers can't alias, so we can change this
|
|
|
|
// into a call to memcpy.
|
|
|
|
if (MemMoveInst *MMI = dyn_cast<MemMoveInst>(MI))
|
|
|
|
if (GlobalVariable *GVSrc = dyn_cast<GlobalVariable>(MMI->getSource()))
|
|
|
|
if (GVSrc->isConstant()) {
|
|
|
|
Module *M = CI.getParent()->getParent()->getParent();
|
|
|
|
Function *MemCpy = M->getOrInsertFunction("llvm.memcpy",
|
|
|
|
CI.getCalledFunction()->getFunctionType());
|
|
|
|
CI.setOperand(0, MemCpy);
|
|
|
|
Changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Changed) return &CI;
|
2004-11-18 21:41:39 +00:00
|
|
|
} else if (DbgStopPointInst *SPI = dyn_cast<DbgStopPointInst>(&CI)) {
|
|
|
|
// If this stoppoint is at the same source location as the previous
|
|
|
|
// stoppoint in the chain, it is not needed.
|
|
|
|
if (DbgStopPointInst *PrevSPI =
|
|
|
|
dyn_cast<DbgStopPointInst>(SPI->getChain()))
|
|
|
|
if (SPI->getLineNo() == PrevSPI->getLineNo() &&
|
|
|
|
SPI->getColNo() == PrevSPI->getColNo()) {
|
|
|
|
SPI->replaceAllUsesWith(PrevSPI);
|
|
|
|
return EraseInstFromFunction(CI);
|
|
|
|
}
|
2004-10-12 04:52:52 +00:00
|
|
|
}
|
|
|
|
|
2003-10-07 22:32:43 +00:00
|
|
|
return visitCallSite(&CI);
|
2003-06-19 17:00:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// InvokeInst simplification
|
|
|
|
//
|
|
|
|
Instruction *InstCombiner::visitInvokeInst(InvokeInst &II) {
|
2003-10-07 22:32:43 +00:00
|
|
|
return visitCallSite(&II);
|
2003-06-19 17:00:31 +00:00
|
|
|
}
|
|
|
|
|
2003-10-07 22:32:43 +00:00
|
|
|
// visitCallSite - Improvements for call and invoke instructions.
|
|
|
|
//
|
|
|
|
Instruction *InstCombiner::visitCallSite(CallSite CS) {
|
2003-10-07 22:54:13 +00:00
|
|
|
bool Changed = false;
|
|
|
|
|
|
|
|
// If the callee is a constexpr cast of a function, attempt to move the cast
|
|
|
|
// to the arguments of the call/invoke.
|
2003-10-07 22:32:43 +00:00
|
|
|
if (transformConstExprCastCall(CS)) return 0;
|
|
|
|
|
2003-10-07 22:54:13 +00:00
|
|
|
Value *Callee = CS.getCalledValue();
|
2004-10-16 18:11:37 +00:00
|
|
|
|
2004-10-18 02:59:09 +00:00
|
|
|
if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee)) {
|
|
|
|
// This instruction is not reachable, just remove it. We insert a store to
|
|
|
|
// undef so that we know that this code is not reachable, despite the fact
|
|
|
|
// that we can't modify the CFG here.
|
|
|
|
new StoreInst(ConstantBool::True,
|
|
|
|
UndefValue::get(PointerType::get(Type::BoolTy)),
|
|
|
|
CS.getInstruction());
|
|
|
|
|
|
|
|
if (!CS.getInstruction()->use_empty())
|
|
|
|
CS.getInstruction()->
|
|
|
|
replaceAllUsesWith(UndefValue::get(CS.getInstruction()->getType()));
|
|
|
|
|
|
|
|
if (InvokeInst *II = dyn_cast<InvokeInst>(CS.getInstruction())) {
|
|
|
|
// Don't break the CFG, insert a dummy cond branch.
|
|
|
|
new BranchInst(II->getNormalDest(), II->getUnwindDest(),
|
|
|
|
ConstantBool::True, II);
|
2004-10-16 18:11:37 +00:00
|
|
|
}
|
2004-10-18 02:59:09 +00:00
|
|
|
return EraseInstFromFunction(*CS.getInstruction());
|
|
|
|
}
|
2004-10-16 18:11:37 +00:00
|
|
|
|
2003-10-07 22:54:13 +00:00
|
|
|
const PointerType *PTy = cast<PointerType>(Callee->getType());
|
|
|
|
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
|
|
|
|
if (FTy->isVarArg()) {
|
|
|
|
// See if we can optimize any arguments passed through the varargs area of
|
|
|
|
// the call.
|
|
|
|
for (CallSite::arg_iterator I = CS.arg_begin()+FTy->getNumParams(),
|
|
|
|
E = CS.arg_end(); I != E; ++I)
|
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(*I)) {
|
|
|
|
// If this cast does not effect the value passed through the varargs
|
|
|
|
// area, we can eliminate the use of the cast.
|
|
|
|
Value *Op = CI->getOperand(0);
|
|
|
|
if (CI->getType()->isLosslesslyConvertibleTo(Op->getType())) {
|
|
|
|
*I = Op;
|
|
|
|
Changed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-10-07 22:32:43 +00:00
|
|
|
|
2003-10-07 22:54:13 +00:00
|
|
|
return Changed ? CS.getInstruction() : 0;
|
2003-10-07 22:32:43 +00:00
|
|
|
}
|
|
|
|
|
2003-06-19 17:00:31 +00:00
|
|
|
// transformConstExprCastCall - If the callee is a constexpr cast of a function,
|
|
|
|
// attempt to move the cast to the arguments of the call/invoke.
|
|
|
|
//
|
|
|
|
bool InstCombiner::transformConstExprCastCall(CallSite CS) {
|
|
|
|
if (!isa<ConstantExpr>(CS.getCalledValue())) return false;
|
|
|
|
ConstantExpr *CE = cast<ConstantExpr>(CS.getCalledValue());
|
2004-07-18 18:59:44 +00:00
|
|
|
if (CE->getOpcode() != Instruction::Cast || !isa<Function>(CE->getOperand(0)))
|
2003-06-19 17:00:31 +00:00
|
|
|
return false;
|
2004-07-18 00:38:32 +00:00
|
|
|
Function *Callee = cast<Function>(CE->getOperand(0));
|
2003-06-19 17:00:31 +00:00
|
|
|
Instruction *Caller = CS.getInstruction();
|
|
|
|
|
|
|
|
// Okay, this is a cast from a function to a different type. Unless doing so
|
|
|
|
// would cause a type conversion of one of our arguments, change this call to
|
|
|
|
// be a direct call with arguments casted to the appropriate types.
|
|
|
|
//
|
|
|
|
const FunctionType *FT = Callee->getFunctionType();
|
|
|
|
const Type *OldRetTy = Caller->getType();
|
|
|
|
|
2004-01-14 06:06:08 +00:00
|
|
|
// Check to see if we are changing the return type...
|
|
|
|
if (OldRetTy != FT->getReturnType()) {
|
|
|
|
if (Callee->isExternal() &&
|
|
|
|
!OldRetTy->isLosslesslyConvertibleTo(FT->getReturnType()) &&
|
|
|
|
!Caller->use_empty())
|
|
|
|
return false; // Cannot transform this return value...
|
|
|
|
|
|
|
|
// If the callsite is an invoke instruction, and the return value is used by
|
|
|
|
// a PHI node in a successor, we cannot change the return type of the call
|
|
|
|
// because there is no place to put the cast instruction (without breaking
|
|
|
|
// the critical edge). Bail out in this case.
|
|
|
|
if (!Caller->use_empty())
|
|
|
|
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller))
|
|
|
|
for (Value::use_iterator UI = II->use_begin(), E = II->use_end();
|
|
|
|
UI != E; ++UI)
|
|
|
|
if (PHINode *PN = dyn_cast<PHINode>(*UI))
|
|
|
|
if (PN->getParent() == II->getNormalDest() ||
|
2004-02-08 21:44:31 +00:00
|
|
|
PN->getParent() == II->getUnwindDest())
|
2004-01-14 06:06:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
2003-06-19 17:00:31 +00:00
|
|
|
|
|
|
|
unsigned NumActualArgs = unsigned(CS.arg_end()-CS.arg_begin());
|
|
|
|
unsigned NumCommonArgs = std::min(FT->getNumParams(), NumActualArgs);
|
|
|
|
|
|
|
|
CallSite::arg_iterator AI = CS.arg_begin();
|
|
|
|
for (unsigned i = 0, e = NumCommonArgs; i != e; ++i, ++AI) {
|
|
|
|
const Type *ParamTy = FT->getParamType(i);
|
|
|
|
bool isConvertible = (*AI)->getType()->isLosslesslyConvertibleTo(ParamTy);
|
|
|
|
if (Callee->isExternal() && !isConvertible) return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FT->getNumParams() < NumActualArgs && !FT->isVarArg() &&
|
|
|
|
Callee->isExternal())
|
|
|
|
return false; // Do not delete arguments unless we have a function body...
|
|
|
|
|
|
|
|
// Okay, we decided that this is a safe thing to do: go ahead and start
|
|
|
|
// inserting cast instructions as necessary...
|
|
|
|
std::vector<Value*> Args;
|
|
|
|
Args.reserve(NumActualArgs);
|
|
|
|
|
|
|
|
AI = CS.arg_begin();
|
|
|
|
for (unsigned i = 0; i != NumCommonArgs; ++i, ++AI) {
|
|
|
|
const Type *ParamTy = FT->getParamType(i);
|
|
|
|
if ((*AI)->getType() == ParamTy) {
|
|
|
|
Args.push_back(*AI);
|
|
|
|
} else {
|
2004-04-08 04:43:23 +00:00
|
|
|
Args.push_back(InsertNewInstBefore(new CastInst(*AI, ParamTy, "tmp"),
|
|
|
|
*Caller));
|
2003-06-19 17:00:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the function takes more arguments than the call was taking, add them
|
|
|
|
// now...
|
|
|
|
for (unsigned i = NumCommonArgs; i != FT->getNumParams(); ++i)
|
|
|
|
Args.push_back(Constant::getNullValue(FT->getParamType(i)));
|
|
|
|
|
|
|
|
// If we are removing arguments to the function, emit an obnoxious warning...
|
|
|
|
if (FT->getNumParams() < NumActualArgs)
|
|
|
|
if (!FT->isVarArg()) {
|
|
|
|
std::cerr << "WARNING: While resolving call to function '"
|
|
|
|
<< Callee->getName() << "' arguments were dropped!\n";
|
|
|
|
} else {
|
|
|
|
// Add all of the arguments in their promoted form to the arg list...
|
|
|
|
for (unsigned i = FT->getNumParams(); i != NumActualArgs; ++i, ++AI) {
|
|
|
|
const Type *PTy = getPromotedType((*AI)->getType());
|
|
|
|
if (PTy != (*AI)->getType()) {
|
|
|
|
// Must promote to pass through va_arg area!
|
|
|
|
Instruction *Cast = new CastInst(*AI, PTy, "tmp");
|
|
|
|
InsertNewInstBefore(Cast, *Caller);
|
|
|
|
Args.push_back(Cast);
|
|
|
|
} else {
|
|
|
|
Args.push_back(*AI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FT->getReturnType() == Type::VoidTy)
|
|
|
|
Caller->setName(""); // Void type should not have a name...
|
|
|
|
|
|
|
|
Instruction *NC;
|
|
|
|
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
|
2004-02-08 21:44:31 +00:00
|
|
|
NC = new InvokeInst(Callee, II->getNormalDest(), II->getUnwindDest(),
|
2003-06-19 17:00:31 +00:00
|
|
|
Args, Caller->getName(), Caller);
|
|
|
|
} else {
|
|
|
|
NC = new CallInst(Callee, Args, Caller->getName(), Caller);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Insert a cast of the return type as necessary...
|
|
|
|
Value *NV = NC;
|
|
|
|
if (Caller->getType() != NV->getType() && !Caller->use_empty()) {
|
|
|
|
if (NV->getType() != Type::VoidTy) {
|
|
|
|
NV = NC = new CastInst(NC, Caller->getType(), "tmp");
|
2003-10-30 00:46:41 +00:00
|
|
|
|
|
|
|
// If this is an invoke instruction, we should insert it after the first
|
|
|
|
// non-phi, instruction in the normal successor block.
|
|
|
|
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
|
|
|
|
BasicBlock::iterator I = II->getNormalDest()->begin();
|
|
|
|
while (isa<PHINode>(I)) ++I;
|
|
|
|
InsertNewInstBefore(NC, *I);
|
|
|
|
} else {
|
|
|
|
// Otherwise, it's a call, just insert cast right after the call instr
|
|
|
|
InsertNewInstBefore(NC, *Caller);
|
|
|
|
}
|
2004-02-28 05:22:00 +00:00
|
|
|
AddUsersToWorkList(*Caller);
|
2003-06-19 17:00:31 +00:00
|
|
|
} else {
|
2004-10-17 21:22:38 +00:00
|
|
|
NV = UndefValue::get(Caller->getType());
|
2003-06-19 17:00:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Caller->getType() != Type::VoidTy && !Caller->use_empty())
|
|
|
|
Caller->replaceAllUsesWith(NV);
|
|
|
|
Caller->getParent()->getInstList().erase(Caller);
|
|
|
|
removeFromWorkList(Caller);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-14 19:13:23 +00:00
|
|
|
// FoldPHIArgOpIntoPHI - If all operands to a PHI node are the same "unary"
|
|
|
|
// operator and they all are only used by the PHI, PHI together their
|
|
|
|
// inputs, and do the operation once, to the result of the PHI.
|
|
|
|
Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
|
|
|
Instruction *FirstInst = cast<Instruction>(PN.getIncomingValue(0));
|
|
|
|
|
|
|
|
// Scan the instruction, looking for input operations that can be folded away.
|
|
|
|
// If all input operands to the phi are the same instruction (e.g. a cast from
|
|
|
|
// the same type or "+42") we can pull the operation through the PHI, reducing
|
|
|
|
// code size and simplifying code.
|
|
|
|
Constant *ConstantOp = 0;
|
|
|
|
const Type *CastSrcTy = 0;
|
|
|
|
if (isa<CastInst>(FirstInst)) {
|
|
|
|
CastSrcTy = FirstInst->getOperand(0)->getType();
|
|
|
|
} else if (isa<BinaryOperator>(FirstInst) || isa<ShiftInst>(FirstInst)) {
|
|
|
|
// Can fold binop or shift if the RHS is a constant.
|
|
|
|
ConstantOp = dyn_cast<Constant>(FirstInst->getOperand(1));
|
|
|
|
if (ConstantOp == 0) return 0;
|
|
|
|
} else {
|
|
|
|
return 0; // Cannot fold this operation.
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if all arguments are the same operation.
|
|
|
|
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
|
|
|
if (!isa<Instruction>(PN.getIncomingValue(i))) return 0;
|
|
|
|
Instruction *I = cast<Instruction>(PN.getIncomingValue(i));
|
|
|
|
if (!I->hasOneUse() || I->getOpcode() != FirstInst->getOpcode())
|
|
|
|
return 0;
|
|
|
|
if (CastSrcTy) {
|
|
|
|
if (I->getOperand(0)->getType() != CastSrcTy)
|
|
|
|
return 0; // Cast operation must match.
|
|
|
|
} else if (I->getOperand(1) != ConstantOp) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Okay, they are all the same operation. Create a new PHI node of the
|
|
|
|
// correct type, and PHI together all of the LHS's of the instructions.
|
|
|
|
PHINode *NewPN = new PHINode(FirstInst->getOperand(0)->getType(),
|
|
|
|
PN.getName()+".in");
|
|
|
|
NewPN->op_reserve(PN.getNumOperands());
|
2004-11-14 19:29:34 +00:00
|
|
|
|
|
|
|
Value *InVal = FirstInst->getOperand(0);
|
|
|
|
NewPN->addIncoming(InVal, PN.getIncomingBlock(0));
|
2004-11-14 19:13:23 +00:00
|
|
|
|
|
|
|
// Add all operands to the new PHI.
|
2004-11-14 19:29:34 +00:00
|
|
|
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
|
|
|
Value *NewInVal = cast<Instruction>(PN.getIncomingValue(i))->getOperand(0);
|
|
|
|
if (NewInVal != InVal)
|
|
|
|
InVal = 0;
|
|
|
|
NewPN->addIncoming(NewInVal, PN.getIncomingBlock(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *PhiVal;
|
|
|
|
if (InVal) {
|
|
|
|
// The new PHI unions all of the same values together. This is really
|
|
|
|
// common, so we handle it intelligently here for compile-time speed.
|
|
|
|
PhiVal = InVal;
|
|
|
|
delete NewPN;
|
|
|
|
} else {
|
|
|
|
InsertNewInstBefore(NewPN, PN);
|
|
|
|
PhiVal = NewPN;
|
|
|
|
}
|
2004-11-14 19:13:23 +00:00
|
|
|
|
|
|
|
// Insert and return the new operation.
|
|
|
|
if (isa<CastInst>(FirstInst))
|
2004-11-14 19:29:34 +00:00
|
|
|
return new CastInst(PhiVal, PN.getType());
|
2004-11-14 19:13:23 +00:00
|
|
|
else if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst))
|
2004-11-14 19:29:34 +00:00
|
|
|
return BinaryOperator::create(BinOp->getOpcode(), PhiVal, ConstantOp);
|
2004-11-14 19:13:23 +00:00
|
|
|
else
|
|
|
|
return new ShiftInst(cast<ShiftInst>(FirstInst)->getOpcode(),
|
2004-11-14 19:29:34 +00:00
|
|
|
PhiVal, ConstantOp);
|
2004-11-14 19:13:23 +00:00
|
|
|
}
|
2002-05-02 17:06:02 +00:00
|
|
|
|
2002-05-06 18:06:38 +00:00
|
|
|
// PHINode simplification
|
|
|
|
//
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
2004-10-17 21:22:38 +00:00
|
|
|
if (Value *V = hasConstantValue(&PN)) {
|
|
|
|
// If V is an instruction, we have to be certain that it dominates PN.
|
|
|
|
// However, because we don't have dom info, we can't do a perfect job.
|
|
|
|
if (Instruction *I = dyn_cast<Instruction>(V)) {
|
|
|
|
// We know that the instruction dominates the PHI if there are no undef
|
|
|
|
// values coming in.
|
2004-10-18 01:48:31 +00:00
|
|
|
if (I->getParent() != &I->getParent()->getParent()->front() ||
|
|
|
|
isa<InvokeInst>(I))
|
2004-10-17 21:31:34 +00:00
|
|
|
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
|
|
|
if (isa<UndefValue>(PN.getIncomingValue(i))) {
|
|
|
|
V = 0;
|
|
|
|
break;
|
|
|
|
}
|
2004-10-17 21:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (V)
|
|
|
|
return ReplaceInstUsesWith(PN, V);
|
|
|
|
}
|
2004-02-16 05:07:08 +00:00
|
|
|
|
|
|
|
// If the only user of this instruction is a cast instruction, and all of the
|
|
|
|
// incoming values are constants, change this PHI to merge together the casted
|
|
|
|
// constants.
|
|
|
|
if (PN.hasOneUse())
|
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(PN.use_back()))
|
|
|
|
if (CI->getType() != PN.getType()) { // noop casts will be folded
|
|
|
|
bool AllConstant = true;
|
|
|
|
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
|
|
|
if (!isa<Constant>(PN.getIncomingValue(i))) {
|
|
|
|
AllConstant = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (AllConstant) {
|
|
|
|
// Make a new PHI with all casted values.
|
|
|
|
PHINode *New = new PHINode(CI->getType(), PN.getName(), &PN);
|
|
|
|
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
|
|
|
|
Constant *OldArg = cast<Constant>(PN.getIncomingValue(i));
|
|
|
|
New->addIncoming(ConstantExpr::getCast(OldArg, New->getType()),
|
|
|
|
PN.getIncomingBlock(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the cast instruction.
|
|
|
|
CI->setOperand(0, New);
|
|
|
|
WorkList.push_back(CI); // revisit the cast instruction to fold.
|
|
|
|
WorkList.push_back(New); // Make sure to revisit the new Phi
|
|
|
|
return &PN; // PN is now dead!
|
|
|
|
}
|
|
|
|
}
|
2004-11-14 19:13:23 +00:00
|
|
|
|
|
|
|
// If all PHI operands are the same operation, pull them through the PHI,
|
|
|
|
// reducing code size.
|
|
|
|
if (isa<Instruction>(PN.getIncomingValue(0)) &&
|
|
|
|
PN.getIncomingValue(0)->hasOneUse())
|
|
|
|
if (Instruction *Result = FoldPHIArgOpIntoPHI(PN))
|
|
|
|
return Result;
|
|
|
|
|
|
|
|
|
2003-12-19 05:58:40 +00:00
|
|
|
return 0;
|
2002-05-06 18:06:38 +00:00
|
|
|
}
|
|
|
|
|
2004-04-05 01:30:19 +00:00
|
|
|
static Value *InsertSignExtendToPtrTy(Value *V, const Type *DTy,
|
|
|
|
Instruction *InsertPoint,
|
|
|
|
InstCombiner *IC) {
|
|
|
|
unsigned PS = IC->getTargetData().getPointerSize();
|
|
|
|
const Type *VTy = V->getType();
|
|
|
|
if (!VTy->isSigned() && VTy->getPrimitiveSize() < PS)
|
|
|
|
// We must insert a cast to ensure we sign-extend.
|
|
|
|
V = IC->InsertNewInstBefore(new CastInst(V, VTy->getSignedVersion(),
|
|
|
|
V->getName()), *InsertPoint);
|
|
|
|
return IC->InsertNewInstBefore(new CastInst(V, DTy, V->getName()),
|
|
|
|
*InsertPoint);
|
|
|
|
}
|
|
|
|
|
2002-05-02 17:06:02 +00:00
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
2004-05-07 22:09:22 +00:00
|
|
|
Value *PtrOp = GEP.getOperand(0);
|
2003-05-22 19:07:21 +00:00
|
|
|
// Is it 'getelementptr %P, long 0' or 'getelementptr %P'
|
2002-06-25 16:13:24 +00:00
|
|
|
// If so, eliminate the noop.
|
2004-02-22 05:25:17 +00:00
|
|
|
if (GEP.getNumOperands() == 1)
|
2004-05-07 22:09:22 +00:00
|
|
|
return ReplaceInstUsesWith(GEP, PtrOp);
|
2004-02-22 05:25:17 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (isa<UndefValue>(GEP.getOperand(0)))
|
|
|
|
return ReplaceInstUsesWith(GEP, UndefValue::get(GEP.getType()));
|
|
|
|
|
2004-02-22 05:25:17 +00:00
|
|
|
bool HasZeroPointerIndex = false;
|
|
|
|
if (Constant *C = dyn_cast<Constant>(GEP.getOperand(1)))
|
|
|
|
HasZeroPointerIndex = C->isNullValue();
|
|
|
|
|
|
|
|
if (GEP.getNumOperands() == 2 && HasZeroPointerIndex)
|
2004-05-07 22:09:22 +00:00
|
|
|
return ReplaceInstUsesWith(GEP, PtrOp);
|
2002-05-02 17:06:02 +00:00
|
|
|
|
2004-04-05 01:30:19 +00:00
|
|
|
// Eliminate unneeded casts for indices.
|
|
|
|
bool MadeChange = false;
|
2004-04-07 18:38:20 +00:00
|
|
|
gep_type_iterator GTI = gep_type_begin(GEP);
|
|
|
|
for (unsigned i = 1, e = GEP.getNumOperands(); i != e; ++i, ++GTI)
|
|
|
|
if (isa<SequentialType>(*GTI)) {
|
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(GEP.getOperand(i))) {
|
|
|
|
Value *Src = CI->getOperand(0);
|
|
|
|
const Type *SrcTy = Src->getType();
|
|
|
|
const Type *DestTy = CI->getType();
|
|
|
|
if (Src->getType()->isInteger()) {
|
|
|
|
if (SrcTy->getPrimitiveSize() == DestTy->getPrimitiveSize()) {
|
|
|
|
// We can always eliminate a cast from ulong or long to the other.
|
|
|
|
// We can always eliminate a cast from uint to int or the other on
|
|
|
|
// 32-bit pointer platforms.
|
|
|
|
if (DestTy->getPrimitiveSize() >= TD->getPointerSize()) {
|
|
|
|
MadeChange = true;
|
|
|
|
GEP.setOperand(i, Src);
|
|
|
|
}
|
|
|
|
} else if (SrcTy->getPrimitiveSize() < DestTy->getPrimitiveSize() &&
|
|
|
|
SrcTy->getPrimitiveSize() == 4) {
|
|
|
|
// We can always eliminate a cast from int to [u]long. We can
|
|
|
|
// eliminate a cast from uint to [u]long iff the target is a 32-bit
|
|
|
|
// pointer target.
|
|
|
|
if (SrcTy->isSigned() ||
|
|
|
|
SrcTy->getPrimitiveSize() >= TD->getPointerSize()) {
|
|
|
|
MadeChange = true;
|
|
|
|
GEP.setOperand(i, Src);
|
|
|
|
}
|
2004-04-05 01:30:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-04-07 18:38:20 +00:00
|
|
|
// If we are using a wider index than needed for this platform, shrink it
|
|
|
|
// to what we need. If the incoming value needs a cast instruction,
|
|
|
|
// insert it. This explicit cast can make subsequent optimizations more
|
|
|
|
// obvious.
|
|
|
|
Value *Op = GEP.getOperand(i);
|
|
|
|
if (Op->getType()->getPrimitiveSize() > TD->getPointerSize())
|
Fix a HUGE pessimization on X86. The indvars pass was taking this
(familiar) function:
int _strlen(const char *str) {
int len = 0;
while (*str++) len++;
return len;
}
And transforming it to use a ulong induction variable, because the type of
the pointer index was left as a constant long. This is obviously very bad.
The fix is to shrink long constants in getelementptr instructions to intptr_t,
making the indvars pass insert a uint induction variable, which is much more
efficient.
Here's the before code for this function:
int %_strlen(sbyte* %str) {
entry:
%tmp.13 = load sbyte* %str ; <sbyte> [#uses=1]
%tmp.24 = seteq sbyte %tmp.13, 0 ; <bool> [#uses=1]
br bool %tmp.24, label %loopexit, label %no_exit
no_exit: ; preds = %entry, %no_exit
*** %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ] ; <uint> [#uses=2]
*** %indvar = phi ulong [ %indvar.next, %no_exit ], [ 0, %entry ] ; <ulong> [#uses=2]
%indvar1 = cast ulong %indvar to uint ; <uint> [#uses=1]
%inc.02.sum = add uint %indvar1, 1 ; <uint> [#uses=1]
%inc.0.0 = getelementptr sbyte* %str, uint %inc.02.sum ; <sbyte*> [#uses=1]
%tmp.1 = load sbyte* %inc.0.0 ; <sbyte> [#uses=1]
%tmp.2 = seteq sbyte %tmp.1, 0 ; <bool> [#uses=1]
%indvar.next = add ulong %indvar, 1 ; <ulong> [#uses=1]
%indvar.next = add uint %indvar, 1 ; <uint> [#uses=1]
br bool %tmp.2, label %loopexit.loopexit, label %no_exit
loopexit.loopexit: ; preds = %no_exit
%indvar = cast uint %indvar to int ; <int> [#uses=1]
%inc.1 = add int %indvar, 1 ; <int> [#uses=1]
ret int %inc.1
loopexit: ; preds = %entry
ret int 0
}
Here's the after code:
int %_strlen(sbyte* %str) {
entry:
%inc.02 = getelementptr sbyte* %str, uint 1 ; <sbyte*> [#uses=1]
%tmp.13 = load sbyte* %str ; <sbyte> [#uses=1]
%tmp.24 = seteq sbyte %tmp.13, 0 ; <bool> [#uses=1]
br bool %tmp.24, label %loopexit, label %no_exit
no_exit: ; preds = %entry, %no_exit
*** %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ] ; <uint> [#uses=3]
%indvar = cast uint %indvar to int ; <int> [#uses=1]
%inc.0.0 = getelementptr sbyte* %inc.02, uint %indvar ; <sbyte*> [#uses=1]
%inc.1 = add int %indvar, 1 ; <int> [#uses=1]
%tmp.1 = load sbyte* %inc.0.0 ; <sbyte> [#uses=1]
%tmp.2 = seteq sbyte %tmp.1, 0 ; <bool> [#uses=1]
%indvar.next = add uint %indvar, 1 ; <uint> [#uses=1]
br bool %tmp.2, label %loopexit, label %no_exit
loopexit: ; preds = %entry, %no_exit
%len.0.1 = phi int [ 0, %entry ], [ %inc.1, %no_exit ] ; <int> [#uses=1]
ret int %len.0.1
}
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13016 91177308-0d34-0410-b5e6-96231b3b80d8
2004-04-17 18:16:10 +00:00
|
|
|
if (Constant *C = dyn_cast<Constant>(Op)) {
|
2004-07-20 01:48:15 +00:00
|
|
|
GEP.setOperand(i, ConstantExpr::getCast(C,
|
|
|
|
TD->getIntPtrType()->getSignedVersion()));
|
Fix a HUGE pessimization on X86. The indvars pass was taking this
(familiar) function:
int _strlen(const char *str) {
int len = 0;
while (*str++) len++;
return len;
}
And transforming it to use a ulong induction variable, because the type of
the pointer index was left as a constant long. This is obviously very bad.
The fix is to shrink long constants in getelementptr instructions to intptr_t,
making the indvars pass insert a uint induction variable, which is much more
efficient.
Here's the before code for this function:
int %_strlen(sbyte* %str) {
entry:
%tmp.13 = load sbyte* %str ; <sbyte> [#uses=1]
%tmp.24 = seteq sbyte %tmp.13, 0 ; <bool> [#uses=1]
br bool %tmp.24, label %loopexit, label %no_exit
no_exit: ; preds = %entry, %no_exit
*** %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ] ; <uint> [#uses=2]
*** %indvar = phi ulong [ %indvar.next, %no_exit ], [ 0, %entry ] ; <ulong> [#uses=2]
%indvar1 = cast ulong %indvar to uint ; <uint> [#uses=1]
%inc.02.sum = add uint %indvar1, 1 ; <uint> [#uses=1]
%inc.0.0 = getelementptr sbyte* %str, uint %inc.02.sum ; <sbyte*> [#uses=1]
%tmp.1 = load sbyte* %inc.0.0 ; <sbyte> [#uses=1]
%tmp.2 = seteq sbyte %tmp.1, 0 ; <bool> [#uses=1]
%indvar.next = add ulong %indvar, 1 ; <ulong> [#uses=1]
%indvar.next = add uint %indvar, 1 ; <uint> [#uses=1]
br bool %tmp.2, label %loopexit.loopexit, label %no_exit
loopexit.loopexit: ; preds = %no_exit
%indvar = cast uint %indvar to int ; <int> [#uses=1]
%inc.1 = add int %indvar, 1 ; <int> [#uses=1]
ret int %inc.1
loopexit: ; preds = %entry
ret int 0
}
Here's the after code:
int %_strlen(sbyte* %str) {
entry:
%inc.02 = getelementptr sbyte* %str, uint 1 ; <sbyte*> [#uses=1]
%tmp.13 = load sbyte* %str ; <sbyte> [#uses=1]
%tmp.24 = seteq sbyte %tmp.13, 0 ; <bool> [#uses=1]
br bool %tmp.24, label %loopexit, label %no_exit
no_exit: ; preds = %entry, %no_exit
*** %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ] ; <uint> [#uses=3]
%indvar = cast uint %indvar to int ; <int> [#uses=1]
%inc.0.0 = getelementptr sbyte* %inc.02, uint %indvar ; <sbyte*> [#uses=1]
%inc.1 = add int %indvar, 1 ; <int> [#uses=1]
%tmp.1 = load sbyte* %inc.0.0 ; <sbyte> [#uses=1]
%tmp.2 = seteq sbyte %tmp.1, 0 ; <bool> [#uses=1]
%indvar.next = add uint %indvar, 1 ; <uint> [#uses=1]
br bool %tmp.2, label %loopexit, label %no_exit
loopexit: ; preds = %entry, %no_exit
%len.0.1 = phi int [ 0, %entry ], [ %inc.1, %no_exit ] ; <int> [#uses=1]
ret int %len.0.1
}
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13016 91177308-0d34-0410-b5e6-96231b3b80d8
2004-04-17 18:16:10 +00:00
|
|
|
MadeChange = true;
|
|
|
|
} else {
|
2004-04-07 18:38:20 +00:00
|
|
|
Op = InsertNewInstBefore(new CastInst(Op, TD->getIntPtrType(),
|
|
|
|
Op->getName()), GEP);
|
|
|
|
GEP.setOperand(i, Op);
|
|
|
|
MadeChange = true;
|
|
|
|
}
|
2004-07-20 01:48:15 +00:00
|
|
|
|
|
|
|
// If this is a constant idx, make sure to canonicalize it to be a signed
|
|
|
|
// operand, otherwise CSE and other optimizations are pessimized.
|
|
|
|
if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op)) {
|
|
|
|
GEP.setOperand(i, ConstantExpr::getCast(CUI,
|
|
|
|
CUI->getType()->getSignedVersion()));
|
|
|
|
MadeChange = true;
|
|
|
|
}
|
2004-04-05 01:30:19 +00:00
|
|
|
}
|
|
|
|
if (MadeChange) return &GEP;
|
|
|
|
|
2002-08-02 19:29:35 +00:00
|
|
|
// Combine Indices - If the source pointer to this getelementptr instruction
|
|
|
|
// is a getelementptr instruction, combine the indices of the two
|
|
|
|
// getelementptr instructions into a single instruction.
|
|
|
|
//
|
2004-03-25 22:59:29 +00:00
|
|
|
std::vector<Value*> SrcGEPOperands;
|
2004-05-07 22:09:22 +00:00
|
|
|
if (GetElementPtrInst *Src = dyn_cast<GetElementPtrInst>(PtrOp)) {
|
2004-03-25 22:59:29 +00:00
|
|
|
SrcGEPOperands.assign(Src->op_begin(), Src->op_end());
|
2004-05-07 22:09:22 +00:00
|
|
|
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOp)) {
|
2004-03-25 22:59:29 +00:00
|
|
|
if (CE->getOpcode() == Instruction::GetElementPtr)
|
|
|
|
SrcGEPOperands.assign(CE->op_begin(), CE->op_end());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!SrcGEPOperands.empty()) {
|
2004-05-07 22:09:22 +00:00
|
|
|
// Note that if our source is a gep chain itself that we wait for that
|
|
|
|
// chain to be resolved before we perform this transformation. This
|
|
|
|
// avoids us creating a TON of code in some cases.
|
|
|
|
//
|
|
|
|
if (isa<GetElementPtrInst>(SrcGEPOperands[0]) &&
|
|
|
|
cast<Instruction>(SrcGEPOperands[0])->getNumOperands() == 2)
|
|
|
|
return 0; // Wait until our source is folded to completion.
|
|
|
|
|
2002-08-02 19:29:35 +00:00
|
|
|
std::vector<Value *> Indices;
|
2004-05-07 22:09:22 +00:00
|
|
|
|
|
|
|
// Find out whether the last index in the source GEP is a sequential idx.
|
|
|
|
bool EndsWithSequential = false;
|
|
|
|
for (gep_type_iterator I = gep_type_begin(*cast<User>(PtrOp)),
|
|
|
|
E = gep_type_end(*cast<User>(PtrOp)); I != E; ++I)
|
2004-05-08 22:41:42 +00:00
|
|
|
EndsWithSequential = !isa<StructType>(*I);
|
2001-12-14 16:52:21 +00:00
|
|
|
|
2002-08-02 19:29:35 +00:00
|
|
|
// Can we combine the two pointer arithmetics offsets?
|
2004-05-07 22:09:22 +00:00
|
|
|
if (EndsWithSequential) {
|
2003-03-05 22:33:14 +00:00
|
|
|
// Replace: gep (gep %P, long B), long A, ...
|
|
|
|
// With: T = long A+B; gep %P, T, ...
|
|
|
|
//
|
2004-05-07 22:09:22 +00:00
|
|
|
Value *Sum, *SO1 = SrcGEPOperands.back(), *GO1 = GEP.getOperand(1);
|
2004-04-05 01:30:19 +00:00
|
|
|
if (SO1 == Constant::getNullValue(SO1->getType())) {
|
|
|
|
Sum = GO1;
|
|
|
|
} else if (GO1 == Constant::getNullValue(GO1->getType())) {
|
|
|
|
Sum = SO1;
|
|
|
|
} else {
|
|
|
|
// If they aren't the same type, convert both to an integer of the
|
|
|
|
// target's pointer size.
|
|
|
|
if (SO1->getType() != GO1->getType()) {
|
|
|
|
if (Constant *SO1C = dyn_cast<Constant>(SO1)) {
|
|
|
|
SO1 = ConstantExpr::getCast(SO1C, GO1->getType());
|
|
|
|
} else if (Constant *GO1C = dyn_cast<Constant>(GO1)) {
|
|
|
|
GO1 = ConstantExpr::getCast(GO1C, SO1->getType());
|
|
|
|
} else {
|
|
|
|
unsigned PS = TD->getPointerSize();
|
|
|
|
if (SO1->getType()->getPrimitiveSize() == PS) {
|
|
|
|
// Convert GO1 to SO1's type.
|
|
|
|
GO1 = InsertSignExtendToPtrTy(GO1, SO1->getType(), &GEP, this);
|
|
|
|
|
|
|
|
} else if (GO1->getType()->getPrimitiveSize() == PS) {
|
|
|
|
// Convert SO1 to GO1's type.
|
|
|
|
SO1 = InsertSignExtendToPtrTy(SO1, GO1->getType(), &GEP, this);
|
|
|
|
} else {
|
|
|
|
const Type *PT = TD->getIntPtrType();
|
|
|
|
SO1 = InsertSignExtendToPtrTy(SO1, PT, &GEP, this);
|
|
|
|
GO1 = InsertSignExtendToPtrTy(GO1, PT, &GEP, this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-05-07 22:09:22 +00:00
|
|
|
if (isa<Constant>(SO1) && isa<Constant>(GO1))
|
|
|
|
Sum = ConstantExpr::getAdd(cast<Constant>(SO1), cast<Constant>(GO1));
|
|
|
|
else {
|
2004-06-10 02:07:29 +00:00
|
|
|
Sum = BinaryOperator::createAdd(SO1, GO1, PtrOp->getName()+".sum");
|
|
|
|
InsertNewInstBefore(cast<Instruction>(Sum), GEP);
|
2004-05-07 22:09:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Recycle the GEP we already have if possible.
|
|
|
|
if (SrcGEPOperands.size() == 2) {
|
|
|
|
GEP.setOperand(0, SrcGEPOperands[0]);
|
|
|
|
GEP.setOperand(1, Sum);
|
|
|
|
return &GEP;
|
|
|
|
} else {
|
|
|
|
Indices.insert(Indices.end(), SrcGEPOperands.begin()+1,
|
|
|
|
SrcGEPOperands.end()-1);
|
|
|
|
Indices.push_back(Sum);
|
|
|
|
Indices.insert(Indices.end(), GEP.op_begin()+2, GEP.op_end());
|
2004-04-05 01:30:19 +00:00
|
|
|
}
|
|
|
|
} else if (isa<Constant>(*GEP.idx_begin()) &&
|
|
|
|
cast<Constant>(*GEP.idx_begin())->isNullValue() &&
|
2004-03-25 22:59:29 +00:00
|
|
|
SrcGEPOperands.size() != 1) {
|
2002-08-02 19:29:35 +00:00
|
|
|
// Otherwise we can do the fold if the first index of the GEP is a zero
|
2004-03-25 22:59:29 +00:00
|
|
|
Indices.insert(Indices.end(), SrcGEPOperands.begin()+1,
|
|
|
|
SrcGEPOperands.end());
|
2002-08-02 19:29:35 +00:00
|
|
|
Indices.insert(Indices.end(), GEP.idx_begin()+1, GEP.idx_end());
|
|
|
|
}
|
2001-12-14 16:52:21 +00:00
|
|
|
|
2002-08-02 19:29:35 +00:00
|
|
|
if (!Indices.empty())
|
2004-03-25 22:59:29 +00:00
|
|
|
return new GetElementPtrInst(SrcGEPOperands[0], Indices, GEP.getName());
|
2002-08-17 22:21:59 +00:00
|
|
|
|
2004-05-07 22:09:22 +00:00
|
|
|
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(PtrOp)) {
|
2002-08-17 22:21:59 +00:00
|
|
|
// GEP of global variable. If all of the indices for this GEP are
|
|
|
|
// constants, we can promote this to a constexpr instead of an instruction.
|
|
|
|
|
|
|
|
// Scan for nonconstants...
|
|
|
|
std::vector<Constant*> Indices;
|
|
|
|
User::op_iterator I = GEP.idx_begin(), E = GEP.idx_end();
|
|
|
|
for (; I != E && isa<Constant>(*I); ++I)
|
|
|
|
Indices.push_back(cast<Constant>(*I));
|
|
|
|
|
|
|
|
if (I == E) { // If they are all constants...
|
2004-07-18 18:59:44 +00:00
|
|
|
Constant *CE = ConstantExpr::getGetElementPtr(GV, Indices);
|
2002-08-17 22:21:59 +00:00
|
|
|
|
|
|
|
// Replace all uses of the GEP with the new constexpr...
|
|
|
|
return ReplaceInstUsesWith(GEP, CE);
|
|
|
|
}
|
2004-05-07 22:09:22 +00:00
|
|
|
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOp)) {
|
2004-02-22 05:25:17 +00:00
|
|
|
if (CE->getOpcode() == Instruction::Cast) {
|
|
|
|
if (HasZeroPointerIndex) {
|
|
|
|
// transform: GEP (cast [10 x ubyte]* X to [0 x ubyte]*), long 0, ...
|
|
|
|
// into : GEP [10 x ubyte]* X, long 0, ...
|
|
|
|
//
|
|
|
|
// This occurs when the program declares an array extern like "int X[];"
|
|
|
|
//
|
|
|
|
Constant *X = CE->getOperand(0);
|
|
|
|
const PointerType *CPTy = cast<PointerType>(CE->getType());
|
|
|
|
if (const PointerType *XTy = dyn_cast<PointerType>(X->getType()))
|
|
|
|
if (const ArrayType *XATy =
|
|
|
|
dyn_cast<ArrayType>(XTy->getElementType()))
|
|
|
|
if (const ArrayType *CATy =
|
|
|
|
dyn_cast<ArrayType>(CPTy->getElementType()))
|
|
|
|
if (CATy->getElementType() == XATy->getElementType()) {
|
|
|
|
// At this point, we know that the cast source type is a pointer
|
|
|
|
// to an array of the same type as the destination pointer
|
|
|
|
// array. Because the array type is never stepped over (there
|
|
|
|
// is a leading zero) we can fold the cast into this GEP.
|
|
|
|
GEP.setOperand(0, X);
|
|
|
|
return &GEP;
|
|
|
|
}
|
2004-11-27 17:55:46 +00:00
|
|
|
} else if (GEP.getNumOperands() == 2) {
|
|
|
|
// Transform things like:
|
|
|
|
// %t = getelementptr ubyte* cast ([2 x sbyte]* %str to ubyte*), uint %V
|
|
|
|
// into: %t1 = getelementptr [2 x sbyte*]* %str, int 0, uint %V; cast
|
|
|
|
Constant *X = CE->getOperand(0);
|
|
|
|
const Type *SrcElTy = cast<PointerType>(X->getType())->getElementType();
|
|
|
|
const Type *ResElTy =cast<PointerType>(CE->getType())->getElementType();
|
|
|
|
if (isa<ArrayType>(SrcElTy) &&
|
|
|
|
TD->getTypeSize(cast<ArrayType>(SrcElTy)->getElementType()) ==
|
|
|
|
TD->getTypeSize(ResElTy)) {
|
|
|
|
Value *V = InsertNewInstBefore(
|
|
|
|
new GetElementPtrInst(X, Constant::getNullValue(Type::IntTy),
|
|
|
|
GEP.getOperand(1), GEP.getName()), GEP);
|
|
|
|
return new CastInst(V, GEP.getType());
|
|
|
|
}
|
2004-02-22 05:25:17 +00:00
|
|
|
}
|
|
|
|
}
|
2001-12-14 16:52:21 +00:00
|
|
|
}
|
2002-08-02 19:29:35 +00:00
|
|
|
|
2001-12-14 16:52:21 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-11-04 16:18:53 +00:00
|
|
|
Instruction *InstCombiner::visitAllocationInst(AllocationInst &AI) {
|
|
|
|
// Convert: malloc Ty, C - where C is a constant != 1 into: malloc [C x Ty], 1
|
|
|
|
if (AI.isArrayAllocation()) // Check C != 1
|
|
|
|
if (const ConstantUInt *C = dyn_cast<ConstantUInt>(AI.getArraySize())) {
|
|
|
|
const Type *NewTy = ArrayType::get(AI.getAllocatedType(), C->getValue());
|
2002-11-09 00:49:43 +00:00
|
|
|
AllocationInst *New = 0;
|
2002-11-04 16:18:53 +00:00
|
|
|
|
|
|
|
// Create and insert the replacement instruction...
|
|
|
|
if (isa<MallocInst>(AI))
|
2004-03-19 06:08:10 +00:00
|
|
|
New = new MallocInst(NewTy, 0, AI.getName());
|
2002-11-09 00:49:43 +00:00
|
|
|
else {
|
|
|
|
assert(isa<AllocaInst>(AI) && "Unknown type of allocation inst!");
|
2004-03-19 06:08:10 +00:00
|
|
|
New = new AllocaInst(NewTy, 0, AI.getName());
|
2002-11-09 00:49:43 +00:00
|
|
|
}
|
2004-03-19 06:08:10 +00:00
|
|
|
|
|
|
|
InsertNewInstBefore(New, AI);
|
2002-11-04 16:18:53 +00:00
|
|
|
|
|
|
|
// Scan to the end of the allocation instructions, to skip over a block of
|
|
|
|
// allocas if possible...
|
|
|
|
//
|
|
|
|
BasicBlock::iterator It = New;
|
|
|
|
while (isa<AllocationInst>(*It)) ++It;
|
|
|
|
|
|
|
|
// Now that I is pointing to the first non-allocation-inst in the block,
|
|
|
|
// insert our getelementptr instruction...
|
|
|
|
//
|
2004-04-05 01:30:19 +00:00
|
|
|
std::vector<Value*> Idx(2, Constant::getNullValue(Type::IntTy));
|
2002-11-04 16:18:53 +00:00
|
|
|
Value *V = new GetElementPtrInst(New, Idx, New->getName()+".sub", It);
|
|
|
|
|
|
|
|
// Now make everything use the getelementptr instead of the original
|
|
|
|
// allocation.
|
2004-03-19 06:08:10 +00:00
|
|
|
return ReplaceInstUsesWith(AI, V);
|
2004-10-16 18:11:37 +00:00
|
|
|
} else if (isa<UndefValue>(AI.getArraySize())) {
|
|
|
|
return ReplaceInstUsesWith(AI, Constant::getNullValue(AI.getType()));
|
2002-11-04 16:18:53 +00:00
|
|
|
}
|
2004-03-19 06:08:10 +00:00
|
|
|
|
|
|
|
// If alloca'ing a zero byte object, replace the alloca with a null pointer.
|
|
|
|
// Note that we only do this for alloca's, because malloc should allocate and
|
|
|
|
// return a unique pointer, even for a zero byte allocation.
|
2004-07-02 22:55:47 +00:00
|
|
|
if (isa<AllocaInst>(AI) && AI.getAllocatedType()->isSized() &&
|
|
|
|
TD->getTypeSize(AI.getAllocatedType()) == 0)
|
2004-03-19 06:08:10 +00:00
|
|
|
return ReplaceInstUsesWith(AI, Constant::getNullValue(AI.getType()));
|
|
|
|
|
2002-11-04 16:18:53 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-12-07 01:24:23 +00:00
|
|
|
Instruction *InstCombiner::visitFreeInst(FreeInst &FI) {
|
|
|
|
Value *Op = FI.getOperand(0);
|
|
|
|
|
|
|
|
// Change free <ty>* (cast <ty2>* X to <ty>*) into free <ty2>* X
|
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(Op))
|
|
|
|
if (isa<PointerType>(CI->getOperand(0)->getType())) {
|
|
|
|
FI.setOperand(0, CI->getOperand(0));
|
|
|
|
return &FI;
|
|
|
|
}
|
|
|
|
|
2004-10-18 02:59:09 +00:00
|
|
|
// free undef -> unreachable.
|
|
|
|
if (isa<UndefValue>(Op)) {
|
|
|
|
// Insert a new store to null because we cannot modify the CFG here.
|
|
|
|
new StoreInst(ConstantBool::True,
|
|
|
|
UndefValue::get(PointerType::get(Type::BoolTy)), &FI);
|
|
|
|
return EraseInstFromFunction(FI);
|
|
|
|
}
|
|
|
|
|
2004-02-28 04:57:37 +00:00
|
|
|
// If we have 'free null' delete the instruction. This can happen in stl code
|
|
|
|
// when lots of inlining happens.
|
2004-10-18 02:59:09 +00:00
|
|
|
if (isa<ConstantPointerNull>(Op))
|
2004-02-28 05:22:00 +00:00
|
|
|
return EraseInstFromFunction(FI);
|
2004-02-28 04:57:37 +00:00
|
|
|
|
2003-12-07 01:24:23 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-06-26 05:06:25 +00:00
|
|
|
/// GetGEPGlobalInitializer - Given a constant, and a getelementptr
|
|
|
|
/// constantexpr, return the constant value being addressed by the constant
|
|
|
|
/// expression, or null if something is funny.
|
|
|
|
///
|
|
|
|
static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) {
|
2004-04-05 01:30:19 +00:00
|
|
|
if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
|
2003-06-26 05:06:25 +00:00
|
|
|
return 0; // Do not allow stepping over the value!
|
|
|
|
|
|
|
|
// Loop over all of the operands, tracking down which value we are
|
|
|
|
// addressing...
|
2004-05-27 17:30:27 +00:00
|
|
|
gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
|
|
|
|
for (++I; I != E; ++I)
|
|
|
|
if (const StructType *STy = dyn_cast<StructType>(*I)) {
|
|
|
|
ConstantUInt *CU = cast<ConstantUInt>(I.getOperand());
|
|
|
|
assert(CU->getValue() < STy->getNumElements() &&
|
|
|
|
"Struct index out of range!");
|
|
|
|
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
|
2004-08-04 08:44:43 +00:00
|
|
|
C = CS->getOperand(CU->getValue());
|
2004-05-27 17:30:27 +00:00
|
|
|
} else if (isa<ConstantAggregateZero>(C)) {
|
|
|
|
C = Constant::getNullValue(STy->getElementType(CU->getValue()));
|
2004-10-16 18:11:37 +00:00
|
|
|
} else if (isa<UndefValue>(C)) {
|
|
|
|
C = UndefValue::get(STy->getElementType(CU->getValue()));
|
2004-05-27 17:30:27 +00:00
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand())) {
|
|
|
|
const ArrayType *ATy = cast<ArrayType>(*I);
|
|
|
|
if ((uint64_t)CI->getRawValue() >= ATy->getNumElements()) return 0;
|
|
|
|
if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
|
2004-08-04 08:44:43 +00:00
|
|
|
C = CA->getOperand(CI->getRawValue());
|
2004-05-27 17:30:27 +00:00
|
|
|
else if (isa<ConstantAggregateZero>(C))
|
|
|
|
C = Constant::getNullValue(ATy->getElementType());
|
2004-10-16 18:11:37 +00:00
|
|
|
else if (isa<UndefValue>(C))
|
|
|
|
C = UndefValue::get(ATy->getElementType());
|
2004-05-27 17:30:27 +00:00
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
} else {
|
2003-06-26 05:06:25 +00:00
|
|
|
return 0;
|
2004-05-27 17:30:27 +00:00
|
|
|
}
|
2003-06-26 05:06:25 +00:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
Factor some code to handle "load (constantexpr cast foo)" just like
"load (cast foo)". This allows us to compile C++ code like this:
class Bclass {
public: virtual int operator()() { return 666; }
};
class Dclass: public Bclass {
public: virtual int operator()() { return 667; }
} ;
int main(int argc, char** argv) {
Dclass x;
return x();
}
Into this:
int %main(int %argc, sbyte** %argv) {
entry:
call void %__main( )
ret int 667
}
Instead of this:
int %main(int %argc, sbyte** %argv) {
entry:
%x = alloca "struct.std::bad_typeid" ; <"struct.std::bad_typeid"*> [#uses=3]
call void %__main( )
%tmp.1.i.i = getelementptr "struct.std::bad_typeid"* %x, uint 0, uint 0, uint 0 ; <int (...)***> [#uses=1]
store int (...)** getelementptr ([3 x int (...)*]* %vtable for Bclass, int 0, long 2), int (...)*** %tmp.1.i.i
%tmp.3.i = getelementptr "struct.std::bad_typeid"* %x, int 0, uint 0, uint 0 ; <int (...)***> [#uses=1]
store int (...)** getelementptr ([3 x int (...)*]* %vtable for Dclass, int 0, long 2), int (...)*** %tmp.3.i
%tmp.5 = load int ("struct.std::bad_typeid"*)** cast (int (...)** getelementptr ([3 x int (...)*]* %vtable for Dclass, int 0, long 2) to int
("struct.std::bad_typeid"*)**) ; <int ("struct.std::bad_typeid"*)*> [#uses=1]
%tmp.6 = call int %tmp.5( "struct.std::bad_typeid"* %x ) ; <int> [#uses=1]
ret int %tmp.6
ret int 0
}
In order words, we now resolve the virtual function call.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14783 91177308-0d34-0410-b5e6-96231b3b80d8
2004-07-13 01:49:43 +00:00
|
|
|
static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI) {
|
|
|
|
User *CI = cast<User>(LI.getOperand(0));
|
|
|
|
|
|
|
|
const Type *DestPTy = cast<PointerType>(CI->getType())->getElementType();
|
|
|
|
if (const PointerType *SrcTy =
|
|
|
|
dyn_cast<PointerType>(CI->getOperand(0)->getType())) {
|
|
|
|
const Type *SrcPTy = SrcTy->getElementType();
|
|
|
|
if (SrcPTy->isSized() && DestPTy->isSized() &&
|
|
|
|
IC.getTargetData().getTypeSize(SrcPTy) ==
|
|
|
|
IC.getTargetData().getTypeSize(DestPTy) &&
|
|
|
|
(SrcPTy->isInteger() || isa<PointerType>(SrcPTy)) &&
|
|
|
|
(DestPTy->isInteger() || isa<PointerType>(DestPTy))) {
|
|
|
|
// Okay, we are casting from one integer or pointer type to another of
|
|
|
|
// the same size. Instead of casting the pointer before the load, cast
|
|
|
|
// the result of the loaded value.
|
|
|
|
Value *NewLoad = IC.InsertNewInstBefore(new LoadInst(CI->getOperand(0),
|
2004-09-19 18:43:46 +00:00
|
|
|
CI->getName(),
|
|
|
|
LI.isVolatile()),LI);
|
Factor some code to handle "load (constantexpr cast foo)" just like
"load (cast foo)". This allows us to compile C++ code like this:
class Bclass {
public: virtual int operator()() { return 666; }
};
class Dclass: public Bclass {
public: virtual int operator()() { return 667; }
} ;
int main(int argc, char** argv) {
Dclass x;
return x();
}
Into this:
int %main(int %argc, sbyte** %argv) {
entry:
call void %__main( )
ret int 667
}
Instead of this:
int %main(int %argc, sbyte** %argv) {
entry:
%x = alloca "struct.std::bad_typeid" ; <"struct.std::bad_typeid"*> [#uses=3]
call void %__main( )
%tmp.1.i.i = getelementptr "struct.std::bad_typeid"* %x, uint 0, uint 0, uint 0 ; <int (...)***> [#uses=1]
store int (...)** getelementptr ([3 x int (...)*]* %vtable for Bclass, int 0, long 2), int (...)*** %tmp.1.i.i
%tmp.3.i = getelementptr "struct.std::bad_typeid"* %x, int 0, uint 0, uint 0 ; <int (...)***> [#uses=1]
store int (...)** getelementptr ([3 x int (...)*]* %vtable for Dclass, int 0, long 2), int (...)*** %tmp.3.i
%tmp.5 = load int ("struct.std::bad_typeid"*)** cast (int (...)** getelementptr ([3 x int (...)*]* %vtable for Dclass, int 0, long 2) to int
("struct.std::bad_typeid"*)**) ; <int ("struct.std::bad_typeid"*)*> [#uses=1]
%tmp.6 = call int %tmp.5( "struct.std::bad_typeid"* %x ) ; <int> [#uses=1]
ret int %tmp.6
ret int 0
}
In order words, we now resolve the virtual function call.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14783 91177308-0d34-0410-b5e6-96231b3b80d8
2004-07-13 01:49:43 +00:00
|
|
|
// Now cast the result of the load.
|
|
|
|
return new CastInst(NewLoad, LI.getType());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-09-19 18:43:46 +00:00
|
|
|
/// isSafeToLoadUnconditionally - Return true if we know that executing a load
|
2004-09-19 19:18:10 +00:00
|
|
|
/// from this value cannot trap. If it is not obviously safe to load from the
|
|
|
|
/// specified pointer, we do a quick local scan of the basic block containing
|
|
|
|
/// ScanFrom, to determine if the address is already accessed.
|
|
|
|
static bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom) {
|
|
|
|
// If it is an alloca or global variable, it is always safe to load from.
|
|
|
|
if (isa<AllocaInst>(V) || isa<GlobalVariable>(V)) return true;
|
|
|
|
|
|
|
|
// Otherwise, be a little bit agressive by scanning the local block where we
|
|
|
|
// want to check to see if the pointer is already being loaded or stored
|
2004-09-20 06:42:58 +00:00
|
|
|
// from/to. If so, the previous load or store would have already trapped,
|
|
|
|
// so there is no harm doing an extra load (also, CSE will later eliminate
|
|
|
|
// the load entirely).
|
2004-09-19 19:18:10 +00:00
|
|
|
BasicBlock::iterator BBI = ScanFrom, E = ScanFrom->getParent()->begin();
|
|
|
|
|
2004-09-20 06:42:58 +00:00
|
|
|
while (BBI != E) {
|
2004-09-19 19:18:10 +00:00
|
|
|
--BBI;
|
|
|
|
|
|
|
|
if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
|
|
|
|
if (LI->getOperand(0) == V) return true;
|
|
|
|
} else if (StoreInst *SI = dyn_cast<StoreInst>(BBI))
|
|
|
|
if (SI->getOperand(1) == V) return true;
|
|
|
|
|
2004-09-20 06:42:58 +00:00
|
|
|
}
|
2004-09-19 19:18:10 +00:00
|
|
|
return false;
|
2004-09-19 18:43:46 +00:00
|
|
|
}
|
|
|
|
|
2003-06-26 05:06:25 +00:00
|
|
|
Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
|
|
|
Value *Op = LI.getOperand(0);
|
2004-01-12 04:13:56 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
if (Constant *C = dyn_cast<Constant>(Op)) {
|
|
|
|
if ((C->isNullValue() || isa<UndefValue>(C)) &&
|
2004-10-18 02:59:09 +00:00
|
|
|
!LI.isVolatile()) { // load null/undef -> undef
|
|
|
|
// Insert a new store to null instruction before the load to indicate that
|
|
|
|
// this code is not reachable. We do this instead of inserting an
|
|
|
|
// unreachable instruction directly because we cannot modify the CFG.
|
|
|
|
new StoreInst(UndefValue::get(LI.getType()), C, &LI);
|
2004-10-16 18:11:37 +00:00
|
|
|
return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType()));
|
2004-10-18 02:59:09 +00:00
|
|
|
}
|
2003-06-26 05:06:25 +00:00
|
|
|
|
2004-10-16 18:11:37 +00:00
|
|
|
// Instcombine load (constant global) into the value loaded.
|
|
|
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
|
|
|
|
if (GV->isConstant() && !GV->isExternal())
|
|
|
|
return ReplaceInstUsesWith(LI, GV->getInitializer());
|
|
|
|
|
|
|
|
// Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded.
|
|
|
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op))
|
|
|
|
if (CE->getOpcode() == Instruction::GetElementPtr) {
|
|
|
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(0)))
|
|
|
|
if (GV->isConstant() && !GV->isExternal())
|
|
|
|
if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
|
|
|
|
return ReplaceInstUsesWith(LI, V);
|
|
|
|
} else if (CE->getOpcode() == Instruction::Cast) {
|
|
|
|
if (Instruction *Res = InstCombineLoadCast(*this, LI))
|
|
|
|
return Res;
|
|
|
|
}
|
|
|
|
}
|
2004-04-08 20:39:49 +00:00
|
|
|
|
|
|
|
// load (cast X) --> cast (load X) iff safe
|
Factor some code to handle "load (constantexpr cast foo)" just like
"load (cast foo)". This allows us to compile C++ code like this:
class Bclass {
public: virtual int operator()() { return 666; }
};
class Dclass: public Bclass {
public: virtual int operator()() { return 667; }
} ;
int main(int argc, char** argv) {
Dclass x;
return x();
}
Into this:
int %main(int %argc, sbyte** %argv) {
entry:
call void %__main( )
ret int 667
}
Instead of this:
int %main(int %argc, sbyte** %argv) {
entry:
%x = alloca "struct.std::bad_typeid" ; <"struct.std::bad_typeid"*> [#uses=3]
call void %__main( )
%tmp.1.i.i = getelementptr "struct.std::bad_typeid"* %x, uint 0, uint 0, uint 0 ; <int (...)***> [#uses=1]
store int (...)** getelementptr ([3 x int (...)*]* %vtable for Bclass, int 0, long 2), int (...)*** %tmp.1.i.i
%tmp.3.i = getelementptr "struct.std::bad_typeid"* %x, int 0, uint 0, uint 0 ; <int (...)***> [#uses=1]
store int (...)** getelementptr ([3 x int (...)*]* %vtable for Dclass, int 0, long 2), int (...)*** %tmp.3.i
%tmp.5 = load int ("struct.std::bad_typeid"*)** cast (int (...)** getelementptr ([3 x int (...)*]* %vtable for Dclass, int 0, long 2) to int
("struct.std::bad_typeid"*)**) ; <int ("struct.std::bad_typeid"*)*> [#uses=1]
%tmp.6 = call int %tmp.5( "struct.std::bad_typeid"* %x ) ; <int> [#uses=1]
ret int %tmp.6
ret int 0
}
In order words, we now resolve the virtual function call.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14783 91177308-0d34-0410-b5e6-96231b3b80d8
2004-07-13 01:49:43 +00:00
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(Op))
|
|
|
|
if (Instruction *Res = InstCombineLoadCast(*this, LI))
|
|
|
|
return Res;
|
2004-04-08 20:39:49 +00:00
|
|
|
|
2004-09-19 18:43:46 +00:00
|
|
|
if (!LI.isVolatile() && Op->hasOneUse()) {
|
|
|
|
// Change select and PHI nodes to select values instead of addresses: this
|
|
|
|
// helps alias analysis out a lot, allows many others simplifications, and
|
|
|
|
// exposes redundancy in the code.
|
|
|
|
//
|
|
|
|
// Note that we cannot do the transformation unless we know that the
|
|
|
|
// introduced loads cannot trap! Something like this is valid as long as
|
|
|
|
// the condition is always false: load (select bool %C, int* null, int* %G),
|
|
|
|
// but it would not be valid if we transformed it to load from null
|
|
|
|
// unconditionally.
|
|
|
|
//
|
|
|
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op)) {
|
|
|
|
// load (select (Cond, &V1, &V2)) --> select(Cond, load &V1, load &V2).
|
2004-09-19 19:18:10 +00:00
|
|
|
if (isSafeToLoadUnconditionally(SI->getOperand(1), SI) &&
|
|
|
|
isSafeToLoadUnconditionally(SI->getOperand(2), SI)) {
|
2004-09-19 18:43:46 +00:00
|
|
|
Value *V1 = InsertNewInstBefore(new LoadInst(SI->getOperand(1),
|
2004-09-20 10:15:10 +00:00
|
|
|
SI->getOperand(1)->getName()+".val"), LI);
|
2004-09-19 18:43:46 +00:00
|
|
|
Value *V2 = InsertNewInstBefore(new LoadInst(SI->getOperand(2),
|
2004-09-20 10:15:10 +00:00
|
|
|
SI->getOperand(2)->getName()+".val"), LI);
|
2004-09-19 18:43:46 +00:00
|
|
|
return new SelectInst(SI->getCondition(), V1, V2);
|
|
|
|
}
|
|
|
|
|
2004-09-23 15:46:00 +00:00
|
|
|
// load (select (cond, null, P)) -> load P
|
|
|
|
if (Constant *C = dyn_cast<Constant>(SI->getOperand(1)))
|
|
|
|
if (C->isNullValue()) {
|
|
|
|
LI.setOperand(0, SI->getOperand(2));
|
|
|
|
return &LI;
|
|
|
|
}
|
|
|
|
|
|
|
|
// load (select (cond, P, null)) -> load P
|
|
|
|
if (Constant *C = dyn_cast<Constant>(SI->getOperand(2)))
|
|
|
|
if (C->isNullValue()) {
|
|
|
|
LI.setOperand(0, SI->getOperand(1));
|
|
|
|
return &LI;
|
|
|
|
}
|
|
|
|
|
2004-09-19 18:43:46 +00:00
|
|
|
} else if (PHINode *PN = dyn_cast<PHINode>(Op)) {
|
|
|
|
// load (phi (&V1, &V2, &V3)) --> phi(load &V1, load &V2, load &V3)
|
2004-09-20 10:15:10 +00:00
|
|
|
bool Safe = PN->getParent() == LI.getParent();
|
|
|
|
|
|
|
|
// Scan all of the instructions between the PHI and the load to make
|
|
|
|
// sure there are no instructions that might possibly alter the value
|
|
|
|
// loaded from the PHI.
|
|
|
|
if (Safe) {
|
|
|
|
BasicBlock::iterator I = &LI;
|
|
|
|
for (--I; !isa<PHINode>(I); --I)
|
|
|
|
if (isa<StoreInst>(I) || isa<CallInst>(I)) {
|
|
|
|
Safe = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e && Safe; ++i)
|
2004-09-19 19:18:10 +00:00
|
|
|
if (!isSafeToLoadUnconditionally(PN->getIncomingValue(i),
|
2004-09-20 10:15:10 +00:00
|
|
|
PN->getIncomingBlock(i)->getTerminator()))
|
2004-09-19 18:43:46 +00:00
|
|
|
Safe = false;
|
2004-09-20 10:15:10 +00:00
|
|
|
|
2004-09-19 18:43:46 +00:00
|
|
|
if (Safe) {
|
|
|
|
// Create the PHI.
|
|
|
|
PHINode *NewPN = new PHINode(LI.getType(), PN->getName());
|
|
|
|
InsertNewInstBefore(NewPN, *PN);
|
|
|
|
std::map<BasicBlock*,Value*> LoadMap; // Don't insert duplicate loads
|
|
|
|
|
|
|
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
|
|
|
|
BasicBlock *BB = PN->getIncomingBlock(i);
|
|
|
|
Value *&TheLoad = LoadMap[BB];
|
|
|
|
if (TheLoad == 0) {
|
|
|
|
Value *InVal = PN->getIncomingValue(i);
|
|
|
|
TheLoad = InsertNewInstBefore(new LoadInst(InVal,
|
|
|
|
InVal->getName()+".val"),
|
|
|
|
*BB->getTerminator());
|
|
|
|
}
|
|
|
|
NewPN->addIncoming(TheLoad, BB);
|
|
|
|
}
|
|
|
|
return ReplaceInstUsesWith(LI, NewPN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-06-26 05:06:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-06-04 04:46:00 +00:00
|
|
|
Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
|
|
|
|
// Change br (not X), label True, label False to: br X, label False, True
|
2004-07-30 07:50:03 +00:00
|
|
|
Value *X;
|
|
|
|
BasicBlock *TrueDest;
|
|
|
|
BasicBlock *FalseDest;
|
|
|
|
if (match(&BI, m_Br(m_Not(m_Value(X)), TrueDest, FalseDest)) &&
|
|
|
|
!isa<Constant>(X)) {
|
|
|
|
// Swap Destinations and condition...
|
|
|
|
BI.setCondition(X);
|
|
|
|
BI.setSuccessor(0, FalseDest);
|
|
|
|
BI.setSuccessor(1, TrueDest);
|
|
|
|
return &BI;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cannonicalize setne -> seteq
|
|
|
|
Instruction::BinaryOps Op; Value *Y;
|
|
|
|
if (match(&BI, m_Br(m_SetCond(Op, m_Value(X), m_Value(Y)),
|
|
|
|
TrueDest, FalseDest)))
|
|
|
|
if ((Op == Instruction::SetNE || Op == Instruction::SetLE ||
|
|
|
|
Op == Instruction::SetGE) && BI.getCondition()->hasOneUse()) {
|
|
|
|
SetCondInst *I = cast<SetCondInst>(BI.getCondition());
|
|
|
|
std::string Name = I->getName(); I->setName("");
|
|
|
|
Instruction::BinaryOps NewOpcode = SetCondInst::getInverseCondition(Op);
|
|
|
|
Value *NewSCC = BinaryOperator::create(NewOpcode, X, Y, Name, I);
|
2003-06-04 05:10:11 +00:00
|
|
|
// Swap Destinations and condition...
|
2004-07-30 07:50:03 +00:00
|
|
|
BI.setCondition(NewSCC);
|
2003-06-04 05:10:11 +00:00
|
|
|
BI.setSuccessor(0, FalseDest);
|
|
|
|
BI.setSuccessor(1, TrueDest);
|
2004-07-30 07:50:03 +00:00
|
|
|
removeFromWorkList(I);
|
|
|
|
I->getParent()->getInstList().erase(I);
|
|
|
|
WorkList.push_back(cast<Instruction>(NewSCC));
|
2003-06-04 05:10:11 +00:00
|
|
|
return &BI;
|
|
|
|
}
|
2004-07-30 07:50:03 +00:00
|
|
|
|
2003-06-04 04:46:00 +00:00
|
|
|
return 0;
|
2004-07-03 00:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) {
|
|
|
|
Value *Cond = SI.getCondition();
|
|
|
|
if (Instruction *I = dyn_cast<Instruction>(Cond)) {
|
|
|
|
if (I->getOpcode() == Instruction::Add)
|
|
|
|
if (ConstantInt *AddRHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
|
|
|
// change 'switch (X+4) case 1:' into 'switch (X) case -3'
|
|
|
|
for (unsigned i = 2, e = SI.getNumOperands(); i != e; i += 2)
|
2004-10-16 18:11:37 +00:00
|
|
|
SI.setOperand(i,ConstantExpr::getSub(cast<Constant>(SI.getOperand(i)),
|
2004-07-03 00:26:11 +00:00
|
|
|
AddRHS));
|
|
|
|
SI.setOperand(0, I->getOperand(0));
|
|
|
|
WorkList.push_back(I);
|
|
|
|
return &SI;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
2003-06-04 04:46:00 +00:00
|
|
|
}
|
2002-11-04 16:18:53 +00:00
|
|
|
|
2001-12-14 16:52:21 +00:00
|
|
|
|
2002-09-02 04:59:56 +00:00
|
|
|
void InstCombiner::removeFromWorkList(Instruction *I) {
|
|
|
|
WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I),
|
|
|
|
WorkList.end());
|
|
|
|
}
|
|
|
|
|
2002-06-25 16:13:24 +00:00
|
|
|
bool InstCombiner::runOnFunction(Function &F) {
|
2002-04-18 17:39:14 +00:00
|
|
|
bool Changed = false;
|
2003-11-02 05:57:39 +00:00
|
|
|
TD = &getAnalysis<TargetData>();
|
2001-12-14 16:52:21 +00:00
|
|
|
|
2004-05-01 23:19:52 +00:00
|
|
|
for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i)
|
|
|
|
WorkList.push_back(&*i);
|
2004-04-27 15:13:33 +00:00
|
|
|
|
2001-12-14 16:52:21 +00:00
|
|
|
|
|
|
|
while (!WorkList.empty()) {
|
|
|
|
Instruction *I = WorkList.back(); // Get an instruction from the worklist
|
|
|
|
WorkList.pop_back();
|
|
|
|
|
2002-10-29 23:06:16 +00:00
|
|
|
// Check to see if we can DCE or ConstantPropagate the instruction...
|
2002-09-02 04:59:56 +00:00
|
|
|
// Check to see if we can DIE the instruction...
|
|
|
|
if (isInstructionTriviallyDead(I)) {
|
|
|
|
// Add operands to the worklist...
|
2003-10-06 17:11:01 +00:00
|
|
|
if (I->getNumOperands() < 4)
|
2004-02-28 05:22:00 +00:00
|
|
|
AddUsesToWorkList(*I);
|
2002-09-02 04:59:56 +00:00
|
|
|
++NumDeadInst;
|
2003-10-06 17:11:01 +00:00
|
|
|
|
|
|
|
I->getParent()->getInstList().erase(I);
|
|
|
|
removeFromWorkList(I);
|
|
|
|
continue;
|
|
|
|
}
|
2002-09-02 04:59:56 +00:00
|
|
|
|
2002-10-29 23:06:16 +00:00
|
|
|
// Instruction isn't dead, see if we can constant propagate it...
|
2002-09-02 04:59:56 +00:00
|
|
|
if (Constant *C = ConstantFoldInstruction(I)) {
|
2004-12-08 23:10:30 +00:00
|
|
|
Value* Ptr = I->getOperand(0);
|
2004-10-16 19:44:59 +00:00
|
|
|
if (isa<GetElementPtrInst>(I) &&
|
2004-12-08 23:10:30 +00:00
|
|
|
cast<Constant>(Ptr)->isNullValue() &&
|
|
|
|
!isa<ConstantPointerNull>(C) &&
|
|
|
|
cast<PointerType>(Ptr->getType())->getElementType()->isSized()) {
|
2004-10-16 19:44:59 +00:00
|
|
|
// If this is a constant expr gep that is effectively computing an
|
|
|
|
// "offsetof", fold it into 'cast int X to T*' instead of 'gep 0, 0, 12'
|
|
|
|
bool isFoldableGEP = true;
|
|
|
|
for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i)
|
|
|
|
if (!isa<ConstantInt>(I->getOperand(i)))
|
|
|
|
isFoldableGEP = false;
|
|
|
|
if (isFoldableGEP) {
|
2004-12-08 23:10:30 +00:00
|
|
|
uint64_t Offset = TD->getIndexedOffset(Ptr->getType(),
|
2004-10-16 19:44:59 +00:00
|
|
|
std::vector<Value*>(I->op_begin()+1, I->op_end()));
|
|
|
|
C = ConstantUInt::get(Type::ULongTy, Offset);
|
2004-10-16 19:46:33 +00:00
|
|
|
C = ConstantExpr::getCast(C, TD->getIntPtrType());
|
2004-10-16 19:44:59 +00:00
|
|
|
C = ConstantExpr::getCast(C, I->getType());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-02 04:59:56 +00:00
|
|
|
// Add operands to the worklist...
|
2004-02-28 05:22:00 +00:00
|
|
|
AddUsesToWorkList(*I);
|
2002-12-05 22:41:53 +00:00
|
|
|
ReplaceInstUsesWith(*I, C);
|
|
|
|
|
2002-09-02 04:59:56 +00:00
|
|
|
++NumConstProp;
|
2003-10-06 17:11:01 +00:00
|
|
|
I->getParent()->getInstList().erase(I);
|
2003-10-07 15:17:02 +00:00
|
|
|
removeFromWorkList(I);
|
2003-10-06 17:11:01 +00:00
|
|
|
continue;
|
2002-09-02 04:59:56 +00:00
|
|
|
}
|
2003-10-06 17:11:01 +00:00
|
|
|
|
2001-12-14 16:52:21 +00:00
|
|
|
// Now that we have an instruction, try combining it to simplify it...
|
2002-08-02 19:29:35 +00:00
|
|
|
if (Instruction *Result = visit(*I)) {
|
2002-05-10 15:38:35 +00:00
|
|
|
++NumCombined;
|
2002-04-18 17:39:14 +00:00
|
|
|
// Should we replace the old instruction with a new one?
|
2002-05-14 15:24:07 +00:00
|
|
|
if (Result != I) {
|
2004-03-13 23:54:27 +00:00
|
|
|
DEBUG(std::cerr << "IC: Old = " << *I
|
|
|
|
<< " New = " << *Result);
|
|
|
|
|
Be more careful about the order we put stuff onto the worklist. This allow us to
collapse this:
bool %le(int %A, int %B) {
%c1 = setgt int %A, %B
%tmp = select bool %c1, int 1, int 0
%c2 = setlt int %A, %B
%result = select bool %c2, int -1, int %tmp
%c3 = setle int %result, 0
ret bool %c3
}
into:
bool %le(int %A, int %B) {
%c3 = setle int %A, %B ; <bool> [#uses=1]
ret bool %c3
}
which is handy, because the Java FE makes these sequences all over the place.
This is tested as: test/Regression/Transforms/InstCombine/JavaCompare.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14086 91177308-0d34-0410-b5e6-96231b3b80d8
2004-06-09 05:08:07 +00:00
|
|
|
// Everything uses the new instruction now.
|
|
|
|
I->replaceAllUsesWith(Result);
|
|
|
|
|
|
|
|
// Push the new instruction and any users onto the worklist.
|
|
|
|
WorkList.push_back(Result);
|
|
|
|
AddUsersToWorkList(*Result);
|
2003-10-06 17:11:01 +00:00
|
|
|
|
|
|
|
// Move the name to the new instruction first...
|
|
|
|
std::string OldName = I->getName(); I->setName("");
|
2003-10-07 22:58:41 +00:00
|
|
|
Result->setName(OldName);
|
2003-10-06 17:11:01 +00:00
|
|
|
|
|
|
|
// Insert the new instruction into the basic block...
|
|
|
|
BasicBlock *InstParent = I->getParent();
|
2004-11-14 19:13:23 +00:00
|
|
|
BasicBlock::iterator InsertPos = I;
|
|
|
|
|
|
|
|
if (!isa<PHINode>(Result)) // If combining a PHI, don't insert
|
|
|
|
while (isa<PHINode>(InsertPos)) // middle of a block of PHIs.
|
|
|
|
++InsertPos;
|
|
|
|
|
|
|
|
InstParent->getInstList().insert(InsertPos, Result);
|
2003-10-06 17:11:01 +00:00
|
|
|
|
2004-05-01 23:27:23 +00:00
|
|
|
// Make sure that we reprocess all operands now that we reduced their
|
|
|
|
// use counts.
|
2004-05-01 23:19:52 +00:00
|
|
|
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
|
|
|
if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(i)))
|
|
|
|
WorkList.push_back(OpI);
|
|
|
|
|
Be more careful about the order we put stuff onto the worklist. This allow us to
collapse this:
bool %le(int %A, int %B) {
%c1 = setgt int %A, %B
%tmp = select bool %c1, int 1, int 0
%c2 = setlt int %A, %B
%result = select bool %c2, int -1, int %tmp
%c3 = setle int %result, 0
ret bool %c3
}
into:
bool %le(int %A, int %B) {
%c3 = setle int %A, %B ; <bool> [#uses=1]
ret bool %c3
}
which is handy, because the Java FE makes these sequences all over the place.
This is tested as: test/Regression/Transforms/InstCombine/JavaCompare.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14086 91177308-0d34-0410-b5e6-96231b3b80d8
2004-06-09 05:08:07 +00:00
|
|
|
// Instructions can end up on the worklist more than once. Make sure
|
|
|
|
// we do not process an instruction that has been deleted.
|
|
|
|
removeFromWorkList(I);
|
2003-10-06 17:11:01 +00:00
|
|
|
|
|
|
|
// Erase the old instruction.
|
|
|
|
InstParent->getInstList().erase(I);
|
2002-06-25 16:13:24 +00:00
|
|
|
} else {
|
2004-03-13 23:54:27 +00:00
|
|
|
DEBUG(std::cerr << "IC: MOD = " << *I);
|
|
|
|
|
2002-08-02 19:29:35 +00:00
|
|
|
// If the instruction was modified, it's possible that it is now dead.
|
|
|
|
// if so, remove it.
|
2004-05-01 23:27:23 +00:00
|
|
|
if (isInstructionTriviallyDead(I)) {
|
|
|
|
// Make sure we process all operands now that we are reducing their
|
|
|
|
// use counts.
|
|
|
|
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
|
|
|
if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(i)))
|
|
|
|
WorkList.push_back(OpI);
|
|
|
|
|
|
|
|
// Instructions may end up in the worklist more than once. Erase all
|
|
|
|
// occurrances of this instruction.
|
2002-09-02 04:59:56 +00:00
|
|
|
removeFromWorkList(I);
|
2004-05-01 23:27:23 +00:00
|
|
|
I->getParent()->getInstList().erase(I);
|
Be more careful about the order we put stuff onto the worklist. This allow us to
collapse this:
bool %le(int %A, int %B) {
%c1 = setgt int %A, %B
%tmp = select bool %c1, int 1, int 0
%c2 = setlt int %A, %B
%result = select bool %c2, int -1, int %tmp
%c3 = setle int %result, 0
ret bool %c3
}
into:
bool %le(int %A, int %B) {
%c3 = setle int %A, %B ; <bool> [#uses=1]
ret bool %c3
}
which is handy, because the Java FE makes these sequences all over the place.
This is tested as: test/Regression/Transforms/InstCombine/JavaCompare.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14086 91177308-0d34-0410-b5e6-96231b3b80d8
2004-06-09 05:08:07 +00:00
|
|
|
} else {
|
|
|
|
WorkList.push_back(Result);
|
|
|
|
AddUsersToWorkList(*Result);
|
2002-08-02 19:29:35 +00:00
|
|
|
}
|
2002-05-14 15:24:07 +00:00
|
|
|
}
|
2002-04-18 17:39:14 +00:00
|
|
|
Changed = true;
|
2001-12-14 16:52:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-04-18 17:39:14 +00:00
|
|
|
return Changed;
|
2002-02-26 21:46:54 +00:00
|
|
|
}
|
|
|
|
|
2004-07-27 17:43:21 +00:00
|
|
|
FunctionPass *llvm::createInstructionCombiningPass() {
|
2002-04-18 17:39:14 +00:00
|
|
|
return new InstCombiner();
|
2002-02-26 21:46:54 +00:00
|
|
|
}
|
2003-11-11 22:41:34 +00:00
|
|
|
|