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.
|
2003-07-23 21:41:57 +00:00
|
|
|
// N. This list is incomplete
|
|
|
|
//
|
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"
|
2003-05-22 19:07:21 +00:00
|
|
|
#include "llvm/Instructions.h"
|
2004-02-28 05:22:00 +00:00
|
|
|
#include "llvm/Intrinsics.h"
|
2002-02-26 21:46:54 +00:00
|
|
|
#include "llvm/Pass.h"
|
2003-05-27 16:40:51 +00:00
|
|
|
#include "llvm/Constants.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-03-13 23:54:27 +00:00
|
|
|
#include "Support/Debug.h"
|
2002-10-01 22:38:41 +00:00
|
|
|
#include "Support/Statistic.h"
|
2002-05-14 15:24:07 +00:00
|
|
|
#include <algorithm>
|
2003-12-07 01:24:23 +00:00
|
|
|
using namespace llvm;
|
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);
|
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.
|
|
|
|
//
|
2004-02-23 06:38:22 +00:00
|
|
|
Value *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
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
I.replaceAllUsesWith(Constant::getNullValue(I.getType()));
|
|
|
|
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);
|
|
|
|
I.getParent()->getInstList().erase(&I);
|
|
|
|
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
|
|
|
|
// operators...
|
|
|
|
bool SimplifyCommutative(BinaryOperator &I);
|
2003-09-19 17:17:26 +00:00
|
|
|
|
|
|
|
Instruction *OptAndOp(Instruction *Op, ConstantIntegral *OpRHS,
|
|
|
|
ConstantIntegral *AndRHS, BinaryOperator &TheAnd);
|
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...
|
|
|
|
// 0 -> Constant, 1 -> Other, 2 -> Argument, 2 -> Unary, 3 -> OtherInst
|
|
|
|
static unsigned getComplexity(Value *V) {
|
|
|
|
if (isa<Instruction>(V)) {
|
|
|
|
if (BinaryOperator::isNeg(V) || BinaryOperator::isNot(V))
|
|
|
|
return 2;
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
if (isa<Argument>(V)) return 2;
|
|
|
|
return isa<Constant>(V) ? 0 : 1;
|
|
|
|
}
|
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-06-10 02:12:35 +00:00
|
|
|
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
|
|
|
|
// non-constant operand of the multiply.
|
|
|
|
//
|
|
|
|
static inline Value *dyn_castFoldableMul(Value *V) {
|
2003-10-15 16:48:29 +00:00
|
|
|
if (V->hasOneUse() && V->getType()->isInteger())
|
2003-03-11 00:12:48 +00:00
|
|
|
if (Instruction *I = dyn_cast<Instruction>(V))
|
|
|
|
if (I->getOpcode() == Instruction::Mul)
|
|
|
|
if (isa<Constant>(I->getOperand(1)))
|
|
|
|
return I->getOperand(0);
|
|
|
|
return 0;
|
2003-02-18 19:28:33 +00:00
|
|
|
}
|
2002-08-14 17:51:49 +00:00
|
|
|
|
2003-03-11 00:12:48 +00:00
|
|
|
// dyn_castMaskingAnd - If this value is an And instruction masking a value with
|
|
|
|
// a constant, return the constant being anded with.
|
|
|
|
//
|
2003-08-12 19:17:27 +00:00
|
|
|
template<class ValueType>
|
|
|
|
static inline Constant *dyn_castMaskingAnd(ValueType *V) {
|
2003-03-11 00:12:48 +00:00
|
|
|
if (Instruction *I = dyn_cast<Instruction>(V))
|
|
|
|
if (I->getOpcode() == Instruction::And)
|
|
|
|
return dyn_cast<Constant>(I->getOperand(1));
|
|
|
|
|
|
|
|
// If this is a constant, it acts just like we were masking with it.
|
|
|
|
return dyn_cast<Constant>(V);
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
if (Constant *C1 = dyn_castMaskingAnd(LHS))
|
2004-06-10 02:07:29 +00:00
|
|
|
return ConstantExpr::getAnd(C1, C2)->isNullValue();
|
2003-08-13 19:01:45 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
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
|
|
|
|
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)) {
|
|
|
|
// 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;
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
2002-05-06 16:49:18 +00:00
|
|
|
|
2003-08-13 19:01:45 +00:00
|
|
|
// X + X --> X << 1
|
|
|
|
if (I.getType()->isInteger())
|
|
|
|
if (Instruction *Result = AssociativeOpt(I, AddRHS(RHS))) return Result;
|
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
|
|
|
|
2003-02-18 19:57:07 +00:00
|
|
|
// X*C + X --> X * (C+1)
|
|
|
|
if (dyn_castFoldableMul(LHS) == RHS) {
|
2003-05-27 16:40:51 +00:00
|
|
|
Constant *CP1 =
|
2004-06-10 02:07:29 +00:00
|
|
|
ConstantExpr::getAdd(
|
2003-05-27 16:40:51 +00:00
|
|
|
cast<Constant>(cast<Instruction>(LHS)->getOperand(1)),
|
|
|
|
ConstantInt::get(I.getType(), 1));
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createMul(RHS, CP1);
|
2003-02-18 19:57:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// X + X*C --> X * (C+1)
|
|
|
|
if (dyn_castFoldableMul(RHS) == LHS) {
|
2003-05-27 16:40:51 +00:00
|
|
|
Constant *CP1 =
|
2004-06-10 02:07:29 +00:00
|
|
|
ConstantExpr::getAdd(
|
2003-05-27 16:40:51 +00:00
|
|
|
cast<Constant>(cast<Instruction>(RHS)->getOperand(1)),
|
|
|
|
ConstantInt::get(I.getType(), 1));
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createMul(LHS, CP1);
|
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
|
|
|
|
if (Constant *C2 = dyn_castMaskingAnd(RHS))
|
|
|
|
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)) {
|
|
|
|
if (Instruction *ILHS = dyn_cast<Instruction>(LHS)) {
|
|
|
|
switch (ILHS->getOpcode()) {
|
|
|
|
case Instruction::Xor:
|
|
|
|
// ~X + C --> (C-1) - X
|
|
|
|
if (ConstantInt *XorRHS = dyn_cast<ConstantInt>(ILHS->getOperand(1)))
|
|
|
|
if (XorRHS->isAllOnesValue())
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSub(ConstantExpr::getSub(CRHS,
|
|
|
|
ConstantInt::get(I.getType(), 1)),
|
2003-10-02 15:11:26 +00:00
|
|
|
ILHS->getOperand(0));
|
|
|
|
break;
|
2004-04-09 19:05:30 +00:00
|
|
|
case Instruction::Select:
|
|
|
|
// Try to fold constant add into select arguments.
|
|
|
|
if (Instruction *R = FoldBinOpIntoSelect(I,cast<SelectInst>(ILHS),this))
|
|
|
|
return R;
|
|
|
|
|
2003-10-02 15:11:26 +00:00
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
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)
|
|
|
|
if (BinaryOperator::isNot(Op1))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAdd(
|
|
|
|
BinaryOperator::getNotArgument(cast<BinaryOperator>(Op1)),
|
|
|
|
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;
|
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
|
|
|
|
|
|
|
// X - X*C --> X * (1-C)
|
|
|
|
if (dyn_castFoldableMul(Op1I) == Op0) {
|
2003-05-27 16:40:51 +00:00
|
|
|
Constant *CP1 =
|
2004-06-10 02:07:29 +00:00
|
|
|
ConstantExpr::getSub(ConstantInt::get(I.getType(), 1),
|
2003-05-27 16:40:51 +00:00
|
|
|
cast<Constant>(cast<Instruction>(Op1)->getOperand(1)));
|
2003-02-18 19:57:07 +00:00
|
|
|
assert(CP1 && "Couldn't constant fold 1-C?");
|
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
|
|
|
|
2003-02-18 19:57:07 +00:00
|
|
|
// X*C - X --> X * (C-1)
|
|
|
|
if (dyn_castFoldableMul(Op0) == Op1) {
|
2003-05-27 16:40:51 +00:00
|
|
|
Constant *CP1 =
|
2004-06-10 02:07:29 +00:00
|
|
|
ConstantExpr::getSub(cast<Constant>(cast<Instruction>(Op0)->getOperand(1)),
|
2003-05-27 16:40:51 +00:00
|
|
|
ConstantInt::get(I.getType(), 1));
|
2003-02-18 19:57:07 +00:00
|
|
|
assert(CP1 && "Couldn't constant fold C - 1?");
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createMul(Op1, CP1);
|
2003-02-18 19:57:07 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
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));
|
|
|
|
} else {
|
|
|
|
ConstantFP *Op1F = cast<ConstantFP>(Op1);
|
|
|
|
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;
|
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) {
|
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));
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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) ||
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
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-06-10 02:07:29 +00:00
|
|
|
Constant *CI = ConstantExpr::getAnd(AndRHS,
|
|
|
|
ConstantExpr::getShl(AllOne, OpRHS));
|
2003-09-19 19:05:02 +00:00
|
|
|
if (CI != AndRHS) {
|
|
|
|
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-06-10 02:07:29 +00:00
|
|
|
Constant *CI = ConstantExpr::getAnd(AndRHS,
|
|
|
|
ConstantExpr::getShr(AllOne, OpRHS));
|
2003-09-19 19:05:02 +00:00
|
|
|
if (CI != AndRHS) {
|
|
|
|
TheAnd.setOperand(1, CI);
|
|
|
|
return &TheAnd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2003-09-19 17:17:26 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-05-06 16:14:14 +00:00
|
|
|
|
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
|
|
|
|
|
|
|
// 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;
|
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()));
|
|
|
|
|
2003-02-18 19:28:33 +00:00
|
|
|
// (~A & ~B) == (~(A | B)) - Demorgan'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);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
// 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
|
|
|
|
2003-07-23 18:29:44 +00:00
|
|
|
if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) {
|
|
|
|
// (X & C1) | C2 --> (X | C2) & (C1|C2)
|
|
|
|
if (Op0I->getOpcode() == Instruction::And && isOnlyUse(Op0))
|
|
|
|
if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
|
|
|
|
std::string Op0Name = Op0I->getName(); Op0I->setName("");
|
2004-06-10 02:07:29 +00:00
|
|
|
Instruction *Or = BinaryOperator::createOr(Op0I->getOperand(0), RHS,
|
|
|
|
Op0Name);
|
2003-07-23 18:29:44 +00:00
|
|
|
InsertNewInstBefore(Or, I);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(Or, ConstantExpr::getOr(RHS, Op0CI));
|
2003-07-23 18:29:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
|
|
|
|
if (Op0I->getOpcode() == Instruction::Xor && isOnlyUse(Op0))
|
|
|
|
if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
|
|
|
|
std::string Op0Name = Op0I->getName(); Op0I->setName("");
|
2004-06-10 02:07:29 +00:00
|
|
|
Instruction *Or = BinaryOperator::createOr(Op0I->getOperand(0), RHS,
|
|
|
|
Op0Name);
|
2003-07-23 18:29:44 +00:00
|
|
|
InsertNewInstBefore(Or, I);
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createXor(Or,
|
2004-06-10 02:12:35 +00:00
|
|
|
ConstantExpr::getAnd(Op0CI,
|
|
|
|
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;
|
2003-07-23 18:29:44 +00:00
|
|
|
}
|
|
|
|
|
2003-08-12 19:11:07 +00:00
|
|
|
// (A & C1)|(A & C2) == A & (C1|C2)
|
2003-08-12 19:17:27 +00:00
|
|
|
if (Instruction *LHS = dyn_cast<BinaryOperator>(Op0))
|
|
|
|
if (Instruction *RHS = dyn_cast<BinaryOperator>(Op1))
|
|
|
|
if (LHS->getOperand(0) == RHS->getOperand(0))
|
|
|
|
if (Constant *C0 = dyn_castMaskingAnd(LHS))
|
|
|
|
if (Constant *C1 = dyn_castMaskingAnd(RHS))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createAnd(LHS->getOperand(0),
|
|
|
|
ConstantExpr::getOr(C0, C1));
|
2003-08-12 19:11:07 +00:00
|
|
|
|
2003-03-10 23:13:59 +00:00
|
|
|
Value *Op0NotVal = dyn_castNotVal(Op0);
|
|
|
|
Value *Op1NotVal = dyn_castNotVal(Op1);
|
|
|
|
|
|
|
|
if (Op1 == Op0NotVal) // ~A | A == -1
|
|
|
|
return ReplaceInstUsesWith(I,
|
|
|
|
ConstantIntegral::getAllOnesValue(I.getType()));
|
2003-02-18 19:28:33 +00:00
|
|
|
|
2003-03-10 23:13:59 +00:00
|
|
|
if (Op0 == Op1NotVal) // A | ~A == -1
|
|
|
|
return ReplaceInstUsesWith(I,
|
|
|
|
ConstantIntegral::getAllOnesValue(I.getType()));
|
|
|
|
|
|
|
|
// (~A | ~B) == (~(A & B)) - Demorgan's Law
|
|
|
|
if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) {
|
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 *And = InsertNewInstBefore(
|
2004-06-10 02:07:29 +00:00
|
|
|
BinaryOperator::createAnd(Op0NotVal,
|
|
|
|
Op1NotVal,I.getName()+".demorgan"),I);
|
2003-03-10 23:13:59 +00:00
|
|
|
return BinaryOperator::createNot(And);
|
|
|
|
}
|
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)
|
|
|
|
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-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-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;
|
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
|
|
|
}
|
|
|
|
|
2003-03-11 00:12:48 +00:00
|
|
|
// (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1^C2 == 0
|
|
|
|
if (Constant *C1 = dyn_castMaskingAnd(Op0))
|
|
|
|
if (Constant *C2 = dyn_castMaskingAnd(Op1))
|
2004-06-10 02:07:29 +00:00
|
|
|
if (ConstantExpr::getAnd(C1, C2)->isNullValue())
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2002-08-09 23:47:40 +00:00
|
|
|
// AddOne, SubOne - Add or subtract a constant one from an integer constant...
|
|
|
|
static Constant *AddOne(ConstantInt *C) {
|
2004-06-10 02:07:29 +00:00
|
|
|
return ConstantExpr::getAdd(C, ConstantInt::get(C->getType(), 1));
|
2002-08-09 23:47:40 +00:00
|
|
|
}
|
|
|
|
static Constant *SubOne(ConstantInt *C) {
|
2004-06-10 02:07:29 +00:00
|
|
|
return ConstantExpr::getSub(C, ConstantInt::get(C->getType(), 1));
|
2002-08-09 23:47:40 +00:00
|
|
|
}
|
|
|
|
|
2002-05-09 20:11:54 +00:00
|
|
|
// isTrueWhenEqual - Return true if the specified setcondinst instruction is
|
|
|
|
// true when both operands are equal...
|
|
|
|
//
|
2002-06-25 16:13:24 +00:00
|
|
|
static bool isTrueWhenEqual(Instruction &I) {
|
|
|
|
return I.getOpcode() == Instruction::SetEQ ||
|
|
|
|
I.getOpcode() == Instruction::SetGE ||
|
|
|
|
I.getOpcode() == Instruction::SetLE;
|
2002-05-09 20:11:54 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2003-08-13 05:38:46 +00:00
|
|
|
// setcc <global/alloca*>, 0 - Global/Stack value addresses are never null!
|
|
|
|
if (isa<ConstantPointerNull>(Op1) &&
|
|
|
|
(isa<GlobalValue>(Op0) || isa<AllocaInst>(Op0)))
|
2002-08-09 23:47:40 +00:00
|
|
|
return ReplaceInstUsesWith(I, ConstantBool::get(!isTrueWhenEqual(I)));
|
|
|
|
|
2003-08-13 05:38:46 +00:00
|
|
|
|
2002-08-09 23:47:40 +00:00
|
|
|
// setcc's with boolean values can always be turned into bitwise operations
|
|
|
|
if (Ty == Type::BoolTy) {
|
|
|
|
// If this is <, >, or !=, we can change this into a simple xor instruction
|
|
|
|
if (!isTrueWhenEqual(I))
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createXor(Op0, Op1);
|
2002-08-09 23:47:40 +00:00
|
|
|
|
|
|
|
// Otherwise we need to make a temporary intermediate instruction and insert
|
|
|
|
// it into the instruction stream. This is what we are after:
|
|
|
|
//
|
|
|
|
// seteq bool %A, %B -> ~(A^B)
|
|
|
|
// setle bool %A, %B -> ~A | B
|
|
|
|
// setge bool %A, %B -> A | ~B
|
|
|
|
//
|
|
|
|
if (I.getOpcode() == Instruction::SetEQ) { // seteq case
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// Handle the setXe cases...
|
|
|
|
assert(I.getOpcode() == Instruction::SetGE ||
|
|
|
|
I.getOpcode() == Instruction::SetLE);
|
|
|
|
|
|
|
|
if (I.getOpcode() == Instruction::SetGE)
|
|
|
|
std::swap(Op0, Op1); // Change setge -> setle
|
|
|
|
|
|
|
|
// Now we just have the SetLE case.
|
2002-08-14 17:51:49 +00:00
|
|
|
Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp");
|
2002-08-09 23:47:40 +00:00
|
|
|
InsertNewInstBefore(Not, I);
|
2004-06-10 02:07:29 +00:00
|
|
|
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-05-25 06:32:08 +00:00
|
|
|
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
|
2004-06-09 04:24:29 +00:00
|
|
|
if (LHSI->hasOneUse())
|
2004-06-09 07:59:58 +00:00
|
|
|
switch (LHSI->getOpcode()) {
|
|
|
|
case Instruction::And:
|
|
|
|
if (isa<ConstantInt>(LHSI->getOperand(1))) {
|
|
|
|
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
if (LHSI->getOperand(0)->hasOneUse())
|
|
|
|
if (ShiftInst *Shift = dyn_cast<ShiftInst>(LHSI->getOperand(0)))
|
|
|
|
if (ConstantUInt *ShAmt =
|
|
|
|
dyn_cast<ConstantUInt>(Shift->getOperand(1))) {
|
|
|
|
ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
const Type *Ty = Shift->getType();
|
|
|
|
if (Shift->getOpcode() != Instruction::Shr ||
|
|
|
|
Shift->getType()->isUnsigned() ||
|
|
|
|
// To test for the bad case of the signed shr, see if any
|
|
|
|
// of the bits shifted in could be tested after the mask.
|
|
|
|
ConstantExpr::getAnd(ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), ConstantUInt::get(Type::UByteTy, Ty->getPrimitiveSize()*8-ShAmt->getValue())), AndCST)->isNullValue()) {
|
|
|
|
unsigned ShiftOp = Shift->getOpcode() == Instruction::Shl
|
|
|
|
? Instruction::Shr : Instruction::Shl;
|
|
|
|
I.setOperand(1, ConstantExpr::get(ShiftOp, CI, ShAmt));
|
|
|
|
LHSI->setOperand(1,ConstantExpr::get(ShiftOp,AndCST,ShAmt));
|
|
|
|
LHSI->setOperand(0, Shift->getOperand(0));
|
|
|
|
WorkList.push_back(Shift); // Shift is probably dead.
|
|
|
|
AddUsesToWorkList(I);
|
|
|
|
return &I;
|
|
|
|
}
|
2004-06-09 04:24:29 +00:00
|
|
|
}
|
2004-06-09 07:59:58 +00:00
|
|
|
}
|
|
|
|
break;
|
2004-06-10 02:07:29 +00:00
|
|
|
case Instruction::Div:
|
|
|
|
if (0 && isa<ConstantInt>(LHSI->getOperand(1))) {
|
|
|
|
std::cerr << "COULD FOLD: " << *LHSI;
|
|
|
|
std::cerr << "COULD FOLD: " << I << "\n";
|
|
|
|
}
|
|
|
|
break;
|
2004-06-09 07:59:58 +00:00
|
|
|
case Instruction::Select:
|
2004-06-09 04:24:29 +00:00
|
|
|
// 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;
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Op1)
|
2004-06-09 07:59:58 +00:00
|
|
|
return new SelectInst(LHSI->getOperand(0), Op1, Op2);
|
|
|
|
break;
|
2004-06-09 04:24:29 +00:00
|
|
|
}
|
2004-05-25 06:32:08 +00:00
|
|
|
|
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))) {
|
|
|
|
return new SetCondInst(I.getOpcode(), BO->getOperand(0),
|
|
|
|
ConstantExpr::getSub(CI, BOp1C));
|
|
|
|
} 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();
|
2003-08-13 05:33:12 +00:00
|
|
|
CastInst *NewCI = new CastInst(X,DestTy,X->getName()+".signed");
|
|
|
|
InsertNewInstBefore(NewCI, I);
|
|
|
|
X = NewCI;
|
|
|
|
}
|
|
|
|
return new SetCondInst(isSetNE ? Instruction::SetLT :
|
|
|
|
Instruction::SetGE, X,
|
|
|
|
Constant::getNullValue(X->getType()));
|
|
|
|
}
|
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
|
|
|
}
|
2003-06-01 03:35:25 +00:00
|
|
|
|
2002-08-09 23:47:40 +00:00
|
|
|
// Check to see if we are comparing against the minimum or maximum value...
|
2002-08-12 21:17:25 +00:00
|
|
|
if (CI->isMinValue()) {
|
2002-08-09 23:47:40 +00:00
|
|
|
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
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetEQ(Op0, Op1);
|
2002-08-09 23:47:40 +00:00
|
|
|
if (I.getOpcode() == Instruction::SetGT) // A > MIN -> A != MIN
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetNE(Op0, Op1);
|
2002-08-09 23:47:40 +00:00
|
|
|
|
2002-08-12 21:17:25 +00:00
|
|
|
} else if (CI->isMaxValue()) {
|
2002-08-09 23:47:40 +00:00
|
|
|
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
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetEQ(Op0, Op1);
|
2002-08-09 23:47:40 +00:00
|
|
|
if (I.getOpcode() == Instruction::SetLT) // A < MAX -> A != MAX
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetNE(Op0, Op1);
|
2002-08-09 23:47:40 +00:00
|
|
|
|
|
|
|
// Comparing against a value really close to min or max?
|
|
|
|
} else if (isMinValuePlusOne(CI)) {
|
|
|
|
if (I.getOpcode() == Instruction::SetLT) // A < MIN+1 -> A == MIN
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetEQ(Op0, SubOne(CI));
|
2002-08-09 23:47:40 +00:00
|
|
|
if (I.getOpcode() == Instruction::SetGE) // A >= MIN-1 -> A != MIN
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetNE(Op0, SubOne(CI));
|
2002-08-09 23:47:40 +00:00
|
|
|
|
|
|
|
} else if (isMaxValueMinusOne(CI)) {
|
|
|
|
if (I.getOpcode() == Instruction::SetGT) // A > MAX-1 -> A == MAX
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetEQ(Op0, AddOne(CI));
|
2002-08-09 23:47:40 +00:00
|
|
|
if (I.getOpcode() == Instruction::SetLE) // A <= MAX-1 -> A != MAX
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetNE(Op0, AddOne(CI));
|
2002-08-09 23:47:40 +00:00
|
|
|
}
|
2004-02-23 05:47:48 +00:00
|
|
|
|
|
|
|
// 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)
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetLT(Op0, AddOne(CI));
|
2004-02-23 05:47:48 +00:00
|
|
|
if (I.getOpcode() == Instruction::SetGE)
|
2004-06-10 02:07:29 +00:00
|
|
|
return BinaryOperator::createSetGT(Op0, SubOne(CI));
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
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;
|
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!
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
const Type *DstTy) {
|
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
|
2002-08-14 23:21:10 +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
|
|
|
|
|
|
|
// 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()) {
|
2002-08-02 20:00:25 +00:00
|
|
|
unsigned SrcSize = SrcTy->getPrimitiveSize();
|
|
|
|
unsigned MidSize = MidTy->getPrimitiveSize();
|
|
|
|
unsigned DstSize = DstTy->getPrimitiveSize();
|
|
|
|
|
2002-08-15 16:15:25 +00:00
|
|
|
// Cases where we are monotonically decreasing the size of the type are
|
|
|
|
// always ok, regardless of what sign changes are going on.
|
|
|
|
//
|
2002-08-14 23:21:10 +00:00
|
|
|
if (SrcSize >= MidSize && MidSize >= DstSize)
|
2002-08-02 20:00:25 +00:00
|
|
|
return true;
|
2002-08-15 16:15:25 +00:00
|
|
|
|
2002-09-23 23:39:43 +00:00
|
|
|
// Cases where the source and destination type are the same, but the middle
|
|
|
|
// type is bigger are noops.
|
|
|
|
//
|
|
|
|
if (SrcSize == DstSize && MidSize > SrcSize)
|
|
|
|
return true;
|
|
|
|
|
2002-08-15 16:15:25 +00:00
|
|
|
// If we are monotonically growing, things are more complex.
|
|
|
|
//
|
|
|
|
if (SrcSize <= MidSize && MidSize <= DstSize) {
|
|
|
|
// We have eight combinations of signedness to worry about. Here's the
|
|
|
|
// table:
|
|
|
|
static const int SignTable[8] = {
|
|
|
|
// CODE, SrcSigned, MidSigned, DstSigned, Comment
|
|
|
|
1, // U U U Always ok
|
|
|
|
1, // U U S Always ok
|
|
|
|
3, // U S U Ok iff SrcSize != MidSize
|
|
|
|
3, // U S S Ok iff SrcSize != MidSize
|
|
|
|
0, // S U U Never ok
|
|
|
|
2, // S U S Ok iff MidSize == DstSize
|
|
|
|
1, // S S U Always ok
|
|
|
|
1, // S S S Always ok
|
|
|
|
};
|
|
|
|
|
|
|
|
// Choose an action based on the current entry of the signtable that this
|
|
|
|
// cast of cast refers to...
|
|
|
|
unsigned Row = SrcTy->isSigned()*4+MidTy->isSigned()*2+DstTy->isSigned();
|
|
|
|
switch (SignTable[Row]) {
|
|
|
|
case 0: return false; // Never ok
|
|
|
|
case 1: return true; // Always ok
|
|
|
|
case 2: return MidSize == DstSize; // Ok iff MidSize == DstSize
|
|
|
|
case 3: // Ok iff SrcSize != MidSize
|
|
|
|
return SrcSize != MidSize || SrcTy == Type::BoolTy;
|
|
|
|
default: assert(0 && "Bad entry in sign table!");
|
|
|
|
}
|
|
|
|
}
|
2002-08-02 20:00:25 +00:00
|
|
|
}
|
2002-05-02 17:06:02 +00:00
|
|
|
|
|
|
|
// Otherwise, we cannot succeed. Specifically we do not want to allow things
|
|
|
|
// like: short -> ushort -> uint, because this can create wrong results if
|
|
|
|
// the input short is negative!
|
|
|
|
//
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2003-07-24 17:35:25 +00:00
|
|
|
static bool ValueRequiresCast(const Value *V, const Type *Ty) {
|
|
|
|
if (V->getType() == Ty || isa<Constant>(V)) return false;
|
|
|
|
if (const CastInst *CI = dyn_cast<CastInst>(V))
|
|
|
|
if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty))
|
|
|
|
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
|
|
|
|
|
|
|
// 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(),
|
|
|
|
CSrc->getType(), CI.getType())) {
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
|
|
|
|
if (DestBitSize == SrcBitSize || !ValueRequiresCast(Op1, DestTy) ||
|
|
|
|
!ValueRequiresCast(Op0, DestTy)) {
|
|
|
|
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-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!!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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.
|
|
|
|
if (Function *F = CI.getCalledFunction())
|
|
|
|
switch (F->getIntrinsicID()) {
|
|
|
|
case Intrinsic::memmove:
|
|
|
|
case Intrinsic::memcpy:
|
|
|
|
case Intrinsic::memset:
|
|
|
|
// memmove/cpy/set of zero bytes is a noop.
|
|
|
|
if (Constant *NumBytes = dyn_cast<Constant>(CI.getOperand(3))) {
|
|
|
|
if (NumBytes->isNullValue())
|
|
|
|
return EraseInstFromFunction(CI);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
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());
|
|
|
|
if (CE->getOpcode() != Instruction::Cast ||
|
|
|
|
!isa<ConstantPointerRef>(CE->getOperand(0)))
|
|
|
|
return false;
|
|
|
|
ConstantPointerRef *CPR = cast<ConstantPointerRef>(CE->getOperand(0));
|
|
|
|
if (!isa<Function>(CPR->getValue())) return false;
|
|
|
|
Function *Callee = cast<Function>(CPR->getValue());
|
|
|
|
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 {
|
|
|
|
NV = Constant::getNullValue(Caller->getType());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Caller->getType() != Type::VoidTy && !Caller->use_empty())
|
|
|
|
Caller->replaceAllUsesWith(NV);
|
|
|
|
Caller->getParent()->getInstList().erase(Caller);
|
|
|
|
removeFromWorkList(Caller);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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) {
|
2003-12-19 05:58:40 +00:00
|
|
|
if (Value *V = hasConstantValue(&PN))
|
|
|
|
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!
|
|
|
|
}
|
|
|
|
}
|
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();
|
|
|
|
Instruction *Cast;
|
|
|
|
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
|
|
|
|
|
|
|
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)) {
|
|
|
|
GEP.setOperand(i, ConstantExpr::getCast(C, TD->getIntPtrType()));
|
|
|
|
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-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();
|
|
|
|
Instruction *Cast;
|
|
|
|
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...
|
2003-04-16 22:40:51 +00:00
|
|
|
Constant *CE =
|
2002-08-17 22:21:59 +00:00
|
|
|
ConstantExpr::getGetElementPtr(ConstantPointerRef::get(GV), Indices);
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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);
|
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-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-02-28 05:22:00 +00:00
|
|
|
if (isa<ConstantPointerNull>(Op))
|
|
|
|
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)) {
|
|
|
|
C = cast<Constant>(CS->getValues()[CU->getValue()]);
|
|
|
|
} else if (isa<ConstantAggregateZero>(C)) {
|
|
|
|
C = Constant::getNullValue(STy->getElementType(CU->getValue()));
|
|
|
|
} 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))
|
|
|
|
C = cast<Constant>(CA->getValues()[CI->getRawValue()]);
|
|
|
|
else if (isa<ConstantAggregateZero>(C))
|
|
|
|
C = Constant::getNullValue(ATy->getElementType());
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
|
|
|
Value *Op = LI.getOperand(0);
|
2004-01-12 04:13:56 +00:00
|
|
|
if (LI.isVolatile()) return 0;
|
|
|
|
|
2004-04-14 03:28:36 +00:00
|
|
|
if (Constant *C = dyn_cast<Constant>(Op))
|
|
|
|
if (C->isNullValue()) // load null -> 0
|
|
|
|
return ReplaceInstUsesWith(LI, Constant::getNullValue(LI.getType()));
|
|
|
|
else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C))
|
|
|
|
Op = CPR->getValue();
|
2003-06-26 05:06:25 +00:00
|
|
|
|
|
|
|
// Instcombine load (constant global) into the value loaded...
|
|
|
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
|
2003-07-22 21:46:59 +00:00
|
|
|
if (GV->isConstant() && !GV->isExternal())
|
2003-06-26 05:06:25 +00:00
|
|
|
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 (ConstantPointerRef *G=dyn_cast<ConstantPointerRef>(CE->getOperand(0)))
|
|
|
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getValue()))
|
2003-07-22 21:46:59 +00:00
|
|
|
if (GV->isConstant() && !GV->isExternal())
|
2003-06-26 05:06:25 +00:00
|
|
|
if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
|
|
|
|
return ReplaceInstUsesWith(LI, V);
|
2004-04-08 20:39:49 +00:00
|
|
|
|
|
|
|
// load (cast X) --> cast (load X) iff safe
|
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(Op)) {
|
|
|
|
const Type *DestPTy = cast<PointerType>(CI->getType())->getElementType();
|
|
|
|
if (const PointerType *SrcTy =
|
|
|
|
dyn_cast<PointerType>(CI->getOperand(0)->getType())) {
|
|
|
|
const Type *SrcPTy = SrcTy->getElementType();
|
2004-05-07 15:35:56 +00:00
|
|
|
if (SrcPTy->isSized() && DestPTy->isSized() &&
|
|
|
|
TD->getTypeSize(SrcPTy) == TD->getTypeSize(DestPTy) &&
|
2004-04-08 20:39:49 +00:00
|
|
|
(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 = InsertNewInstBefore(new LoadInst(CI->getOperand(0),
|
|
|
|
CI->getName()), LI);
|
|
|
|
// Now cast the result of the load.
|
|
|
|
return new CastInst(NewLoad, LI.getType());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-02-27 06:27:46 +00:00
|
|
|
if (BI.isConditional() && !isa<Constant>(BI.getCondition())) {
|
2003-06-04 05:10:11 +00:00
|
|
|
if (Value *V = dyn_castNotVal(BI.getCondition())) {
|
|
|
|
BasicBlock *TrueDest = BI.getSuccessor(0);
|
|
|
|
BasicBlock *FalseDest = BI.getSuccessor(1);
|
|
|
|
// Swap Destinations and condition...
|
|
|
|
BI.setCondition(V);
|
|
|
|
BI.setSuccessor(0, FalseDest);
|
|
|
|
BI.setSuccessor(1, TrueDest);
|
|
|
|
return &BI;
|
2004-02-27 06:27:46 +00:00
|
|
|
} else if (SetCondInst *I = dyn_cast<SetCondInst>(BI.getCondition())) {
|
|
|
|
// Cannonicalize setne -> seteq
|
|
|
|
if ((I->getOpcode() == Instruction::SetNE ||
|
|
|
|
I->getOpcode() == Instruction::SetLE ||
|
|
|
|
I->getOpcode() == Instruction::SetGE) && I->hasOneUse()) {
|
|
|
|
std::string Name = I->getName(); I->setName("");
|
|
|
|
Instruction::BinaryOps NewOpcode =
|
|
|
|
SetCondInst::getInverseCondition(I->getOpcode());
|
|
|
|
Value *NewSCC = BinaryOperator::create(NewOpcode, I->getOperand(0),
|
|
|
|
I->getOperand(1), Name, I);
|
|
|
|
BasicBlock *TrueDest = BI.getSuccessor(0);
|
|
|
|
BasicBlock *FalseDest = BI.getSuccessor(1);
|
|
|
|
// Swap Destinations and condition...
|
|
|
|
BI.setCondition(NewSCC);
|
|
|
|
BI.setSuccessor(0, FalseDest);
|
|
|
|
BI.setSuccessor(1, TrueDest);
|
|
|
|
removeFromWorkList(I);
|
|
|
|
I->getParent()->getInstList().erase(I);
|
|
|
|
WorkList.push_back(cast<Instruction>(NewSCC));
|
|
|
|
return &BI;
|
|
|
|
}
|
2003-06-04 05:10:11 +00:00
|
|
|
}
|
2004-02-27 06:27:46 +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)
|
|
|
|
SI.setOperand(i, ConstantExpr::getSub(cast<Constant>(SI.getOperand(i)),
|
|
|
|
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)) {
|
|
|
|
// 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
|
|
|
|
2004-03-25 22:59:29 +00:00
|
|
|
// Check to see if any of the operands of this instruction are a
|
|
|
|
// ConstantPointerRef. Since they sneak in all over the place and inhibit
|
|
|
|
// optimization, we want to strip them out unconditionally!
|
|
|
|
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
|
|
|
if (ConstantPointerRef *CPR =
|
|
|
|
dyn_cast<ConstantPointerRef>(I->getOperand(i))) {
|
|
|
|
I->setOperand(i, CPR->getValue());
|
|
|
|
Changed = true;
|
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
InstParent->getInstList().insert(I, Result);
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2003-12-07 01:24:23 +00:00
|
|
|
Pass *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
|
|
|
|