mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Factorize common code out of the InstructionSimplify shift logic. Add in
threading of shifts over selects and phis while there. This fires here and there in the testsuite, to not much effect. For example when compiling spirit it fires 5 times, during early-cse, resulting in 6 more cse simplifications, and 3 more terminators being folded by jump threading, but the final bitcode doesn't change in any interesting way: other optimizations would have caught the opportunity anyway, only later. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123441 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
62becca681
commit
cf80bc1d4a
@ -684,31 +684,27 @@ Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
return ::SimplifyMulInst(Op0, Op1, TD, DT, RecursionLimit);
|
||||
}
|
||||
|
||||
/// SimplifyShlInst - Given operands for an Shl, see if we can
|
||||
/// SimplifyShift - Given operands for an Shl, LShr or AShr, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
static Value *SimplifyShlInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
const DominatorTree *DT, unsigned MaxRecurse) {
|
||||
static Value *SimplifyShift(unsigned Opcode, Value *Op0, Value *Op1,
|
||||
const TargetData *TD, const DominatorTree *DT,
|
||||
unsigned MaxRecurse) {
|
||||
if (Constant *C0 = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *C1 = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { C0, C1 };
|
||||
return ConstantFoldInstOperands(Instruction::Shl, C0->getType(), Ops, 2,
|
||||
TD);
|
||||
return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, 2, TD);
|
||||
}
|
||||
}
|
||||
|
||||
// 0 << X -> 0
|
||||
// 0 shift by X -> 0
|
||||
if (match(Op0, m_Zero()))
|
||||
return Op0;
|
||||
|
||||
// X << 0 -> X
|
||||
// X shift by 0 -> X
|
||||
if (match(Op1, m_Zero()))
|
||||
return Op0;
|
||||
|
||||
// undef << X -> 0
|
||||
if (isa<UndefValue>(Op0))
|
||||
return Constant::getNullValue(Op0->getType());
|
||||
|
||||
// X << undef -> undef because it may shift by the bitwidth.
|
||||
// X shift by undef -> undef because it may shift by the bitwidth.
|
||||
if (isa<UndefValue>(Op1))
|
||||
return Op1;
|
||||
|
||||
@ -718,6 +714,32 @@ static Value *SimplifyShlInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
Op0->getType()->getScalarSizeInBits())
|
||||
return UndefValue::get(Op0->getType());
|
||||
|
||||
// If the operation is with the result of a select instruction, check whether
|
||||
// operating on either branch of the select always yields the same value.
|
||||
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
|
||||
if (Value *V = ThreadBinOpOverSelect(Opcode, Op0, Op1, TD, DT, MaxRecurse))
|
||||
return V;
|
||||
|
||||
// If the operation is with the result of a phi instruction, check whether
|
||||
// operating on all incoming values of the phi always yields the same value.
|
||||
if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
|
||||
if (Value *V = ThreadBinOpOverPHI(Opcode, Op0, Op1, TD, DT, MaxRecurse))
|
||||
return V;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// SimplifyShlInst - Given operands for an Shl, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
static Value *SimplifyShlInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
const DominatorTree *DT, unsigned MaxRecurse) {
|
||||
if (Value *V = SimplifyShift(Instruction::Shl, Op0, Op1, TD, DT, MaxRecurse))
|
||||
return V;
|
||||
|
||||
// undef << X -> 0
|
||||
if (isa<UndefValue>(Op0))
|
||||
return Constant::getNullValue(Op0->getType());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -730,36 +752,13 @@ Value *llvm::SimplifyShlInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
/// fold the result. If not, this returns null.
|
||||
static Value *SimplifyLShrInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
const DominatorTree *DT, unsigned MaxRecurse) {
|
||||
if (Constant *C0 = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *C1 = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { C0, C1 };
|
||||
return ConstantFoldInstOperands(Instruction::LShr, C0->getType(), Ops, 2,
|
||||
TD);
|
||||
}
|
||||
}
|
||||
|
||||
// 0 >> X -> 0
|
||||
if (match(Op0, m_Zero()))
|
||||
return Op0;
|
||||
if (Value *V = SimplifyShift(Instruction::LShr, Op0, Op1, TD, DT, MaxRecurse))
|
||||
return V;
|
||||
|
||||
// undef >>l X -> 0
|
||||
if (isa<UndefValue>(Op0))
|
||||
return Constant::getNullValue(Op0->getType());
|
||||
|
||||
// X >> 0 -> X
|
||||
if (match(Op1, m_Zero()))
|
||||
return Op0;
|
||||
|
||||
// X >> undef -> undef because it may shift by the bitwidth.
|
||||
if (isa<UndefValue>(Op1))
|
||||
return Op1;
|
||||
|
||||
// Shifting by the bitwidth or more is undefined.
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1))
|
||||
if (CI->getValue().getLimitedValue() >=
|
||||
Op0->getType()->getScalarSizeInBits())
|
||||
return UndefValue::get(Op0->getType());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -772,17 +771,8 @@ Value *llvm::SimplifyLShrInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
/// fold the result. If not, this returns null.
|
||||
static Value *SimplifyAShrInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
const DominatorTree *DT, unsigned MaxRecurse) {
|
||||
if (Constant *C0 = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *C1 = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { C0, C1 };
|
||||
return ConstantFoldInstOperands(Instruction::AShr, C0->getType(), Ops, 2,
|
||||
TD);
|
||||
}
|
||||
}
|
||||
|
||||
// 0 >> X -> 0
|
||||
if (match(Op0, m_Zero()))
|
||||
return Op0;
|
||||
if (Value *V = SimplifyShift(Instruction::AShr, Op0, Op1, TD, DT, MaxRecurse))
|
||||
return V;
|
||||
|
||||
// all ones >>a X -> all ones
|
||||
if (match(Op0, m_AllOnes()))
|
||||
@ -792,20 +782,6 @@ static Value *SimplifyAShrInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
if (isa<UndefValue>(Op0))
|
||||
return Constant::getAllOnesValue(Op0->getType());
|
||||
|
||||
// X >> 0 -> X
|
||||
if (match(Op1, m_Zero()))
|
||||
return Op0;
|
||||
|
||||
// X >> undef -> undef because it may shift by the bitwidth.
|
||||
if (isa<UndefValue>(Op1))
|
||||
return Op1;
|
||||
|
||||
// Shifting by the bitwidth or more is undefined.
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1))
|
||||
if (CI->getValue().getLimitedValue() >=
|
||||
Op0->getType()->getScalarSizeInBits())
|
||||
return UndefValue::get(Op0->getType());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
9
test/Transforms/InstSimplify/2011-01-14-Thread.ll
Normal file
9
test/Transforms/InstSimplify/2011-01-14-Thread.ll
Normal file
@ -0,0 +1,9 @@
|
||||
; RUN: opt < %s -instsimplify -S | FileCheck %s
|
||||
|
||||
define i32 @shift_select(i1 %cond) {
|
||||
; CHECK: @shift_select
|
||||
%s = select i1 %cond, i32 0, i32 1
|
||||
%r = lshr i32 %s, 1
|
||||
ret i32 %r
|
||||
; CHECK: ret i32 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user