[llvm-commits] [llvm] r123441 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/2011-01-14-Thread.ll

Duncan Sands baldrick at free.fr
Fri Jan 14 06:44:13 PST 2011


Author: baldrick
Date: Fri Jan 14 08:44:12 2011
New Revision: 123441

URL: http://llvm.org/viewvc/llvm-project?rev=123441&view=rev
Log:
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.

Added:
    llvm/trunk/test/Transforms/InstSimplify/2011-01-14-Thread.ll
Modified:
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=123441&r1=123440&r2=123441&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Fri Jan 14 08:44:12 2011
@@ -684,31 +684,27 @@
   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 @@
         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 @@
 /// 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 @@
 /// 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 @@
   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;
 }
 

Added: llvm/trunk/test/Transforms/InstSimplify/2011-01-14-Thread.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2011-01-14-Thread.ll?rev=123441&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/2011-01-14-Thread.ll (added)
+++ llvm/trunk/test/Transforms/InstSimplify/2011-01-14-Thread.ll Fri Jan 14 08:44:12 2011
@@ -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
+}





More information about the llvm-commits mailing list