From cf80bc1d4ac741620641c2bf48c25993bd478bd0 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 14 Jan 2011 14:44:12 +0000 Subject: [PATCH] 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 --- lib/Analysis/InstructionSimplify.cpp | 100 +++++++----------- .../InstSimplify/2011-01-14-Thread.ll | 9 ++ 2 files changed, 47 insertions(+), 62 deletions(-) create mode 100644 test/Transforms/InstSimplify/2011-01-14-Thread.ll diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 29ce5cfd430..d5cf626e60f 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -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(Op0)) { if (Constant *C1 = dyn_cast(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(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(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(Op0) || isa(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(Op0) || isa(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(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(Op0)) { - if (Constant *C1 = dyn_cast(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(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(Op1)) - return Op1; - - // Shifting by the bitwidth or more is undefined. - if (ConstantInt *CI = dyn_cast(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(Op0)) { - if (Constant *C1 = dyn_cast(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(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(Op1)) - return Op1; - - // Shifting by the bitwidth or more is undefined. - if (ConstantInt *CI = dyn_cast(Op1)) - if (CI->getValue().getLimitedValue() >= - Op0->getType()->getScalarSizeInBits()) - return UndefValue::get(Op0->getType()); - return 0; } diff --git a/test/Transforms/InstSimplify/2011-01-14-Thread.ll b/test/Transforms/InstSimplify/2011-01-14-Thread.ll new file mode 100644 index 00000000000..8fc4dc5d5bb --- /dev/null +++ b/test/Transforms/InstSimplify/2011-01-14-Thread.ll @@ -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 +} -- 2.34.1