[llvm-commits] [llvm] r94339 - in /llvm/trunk: include/llvm/Support/PatternMatch.h lib/Target/PowerPC/README.txt lib/Transforms/InstCombine/InstCombineAndOrXor.cpp lib/Transforms/InstCombine/InstCombineCasts.cpp lib/Transforms/InstCombine/InstCombineSelect.cpp test/Transforms/InstCombine/logical-select.ll

Chris Lattner sabre at nondot.org
Sat Jan 23 16:09:49 PST 2010


Author: lattner
Date: Sat Jan 23 18:09:49 2010
New Revision: 94339

URL: http://llvm.org/viewvc/llvm-project?rev=94339&view=rev
Log:
change the canonical form of "cond ? -1 : 0" to be 
"sext cond" instead of a select.  This simplifies some instcombine
code, matches the policy for zext (cond ? 1 : 0 -> zext), and allows
us to generate better code for a testcase on ppc.

Modified:
    llvm/trunk/include/llvm/Support/PatternMatch.h
    llvm/trunk/lib/Target/PowerPC/README.txt
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/trunk/test/Transforms/InstCombine/logical-select.ll

Modified: llvm/trunk/include/llvm/Support/PatternMatch.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PatternMatch.h?rev=94339&r1=94338&r2=94339&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/PatternMatch.h (original)
+++ llvm/trunk/include/llvm/Support/PatternMatch.h Sat Jan 23 18:09:49 2010
@@ -423,7 +423,7 @@
 }
 
 /// m_SelectCst - This matches a select of two constants, e.g.:
-///    m_SelectCst(m_Value(V), -1, 0)
+///    m_SelectCst<-1, 0>(m_Value(V))
 template<int64_t L, int64_t R, typename Cond>
 inline SelectClass_match<Cond, constantint_ty<L>, constantint_ty<R> >
 m_SelectCst(const Cond &C) {
@@ -466,6 +466,20 @@
 m_Trunc(const OpTy &Op) {
   return CastClass_match<OpTy, Instruction::Trunc>(Op);
 }
+
+/// m_SExt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::SExt>
+m_SExt(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::SExt>(Op);
+}
+
+/// m_ZExt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::ZExt>
+m_ZExt(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::ZExt>(Op);
+}
   
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/PowerPC/README.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/README.txt?rev=94339&r1=94338&r2=94339&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/README.txt (original)
+++ llvm/trunk/lib/Target/PowerPC/README.txt Sat Jan 23 18:09:49 2010
@@ -640,22 +640,19 @@
 define i32 @bar(i32 %x) nounwind readnone ssp {
 entry:
   %0 = icmp eq i32 %x, 0                          ; <i1> [#uses=1]
-  %neg = select i1 %0, i32 -1, i32 0              ; <i32> [#uses=1]
+  %neg = sext i1 %0 to i32              ; <i32> [#uses=1]
   ret i32 %neg
 }
 
 to:
 
 _bar:
-	cmplwi cr0, r3, 0
-	li r3, -1
-	beq cr0, LBB1_2
-; BB#1:                                                     ; %entry
-	li r3, 0
-LBB1_2:                                                     ; %entry
+	cntlzw r2, r3
+	slwi r2, r2, 26
+	srawi r3, r2, 31
 	blr 
 
-it would be much better to produce:
+it would be better to produce:
 
 _bar: 
         addic r3,r3,-1

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=94339&r1=94338&r2=94339&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Sat Jan 23 18:09:49 2010
@@ -1142,19 +1142,15 @@
                                          Value *C, Value *D) {
   // If A is not a select of -1/0, this cannot match.
   Value *Cond = 0;
-  if (!match(A, m_SelectCst<-1, 0>(m_Value(Cond))))
+  if (!match(A, m_SExt(m_Value(Cond))))
     return 0;
 
   // ((cond?-1:0)&C) | (B&(cond?0:-1)) -> cond ? C : B.
-  if (match(D, m_SelectCst<0, -1>(m_Specific(Cond))))
-    return SelectInst::Create(Cond, C, B);
-  if (match(D, m_Not(m_SelectCst<-1, 0>(m_Specific(Cond)))))
+  if (match(D, m_Not(m_SExt(m_Specific(Cond)))))
     return SelectInst::Create(Cond, C, B);
   // ((cond?-1:0)&C) | ((cond?0:-1)&D) -> cond ? C : D.
   if (match(B, m_SelectCst<0, -1>(m_Specific(Cond))))
     return SelectInst::Create(Cond, C, D);
-  if (match(B, m_Not(m_SelectCst<-1, 0>(m_Specific(Cond)))))
-    return SelectInst::Create(Cond, C, D);
   return 0;
 }
 

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=94339&r1=94338&r2=94339&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Sat Jan 23 18:09:49 2010
@@ -923,12 +923,6 @@
   Value *Src = CI.getOperand(0);
   const Type *SrcTy = Src->getType(), *DestTy = CI.getType();
 
-  // Canonicalize sign-extend from i1 to a select.
-  if (Src->getType()->isInteger(1))
-    return SelectInst::Create(Src,
-                              Constant::getAllOnesValue(CI.getType()),
-                              Constant::getNullValue(CI.getType()));
-  
   // Attempt to extend the entire input expression tree to the destination
   // type.   Only do this if the dest type is a simple type, don't convert the
   // expression tree to something weird like i93 unless the source is also
@@ -968,6 +962,30 @@
       return BinaryOperator::CreateAShr(Res, ShAmt);
     }
   
+  
+  // (x <s 0) ? -1 : 0 -> ashr x, 31   -> all ones if signed
+  // (x >s -1) ? -1 : 0 -> ashr x, 31  -> all ones if not signed
+  {
+  ICmpInst::Predicate Pred; Value *CmpLHS; ConstantInt *CmpRHS;
+  if (match(Src, m_ICmp(Pred, m_Value(CmpLHS), m_ConstantInt(CmpRHS)))) {
+    // sext (x <s  0) to i32 --> x>>s31       true if signbit set.
+    // sext (x >s -1) to i32 --> (x>>s31)^-1  true if signbit clear.
+    if ((Pred == ICmpInst::ICMP_SLT && CmpRHS->isZero()) ||
+        (Pred == ICmpInst::ICMP_SGT && CmpRHS->isAllOnesValue())) {
+      Value *Sh = ConstantInt::get(CmpLHS->getType(),
+                                   CmpLHS->getType()->getScalarSizeInBits()-1);
+      Value *In = Builder->CreateAShr(CmpLHS, Sh, CmpLHS->getName()+".lobit");
+      if (In->getType() != CI.getType())
+        In = Builder->CreateIntCast(In, CI.getType(), true/*SExt*/, "tmp");
+      
+      if (Pred == ICmpInst::ICMP_SGT)
+        In = Builder->CreateNot(In, In->getName()+".not");
+      return ReplaceInstUsesWith(CI, In);
+    }
+  }
+  }
+  
+  
   // If the input is a shl/ashr pair of a same constant, then this is a sign
   // extension from a smaller value.  If we could trust arbitrary bitwidth
   // integers, we could turn this into a truncate to the smaller bit and then

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=94339&r1=94338&r2=94339&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Sat Jan 23 18:09:49 2010
@@ -326,44 +326,6 @@
         break;
       }
       }
-
-      // (x <s 0) ? -1 : 0 -> ashr x, 31   -> all ones if signed
-      // (x >s -1) ? -1 : 0 -> ashr x, 31  -> all ones if not signed
-      CmpInst::Predicate Pred = CmpInst::BAD_ICMP_PREDICATE;
-      if (match(TrueVal, m_ConstantInt<-1>()) &&
-          match(FalseVal, m_ConstantInt<0>()))
-        Pred = ICI->getPredicate();
-      else if (match(TrueVal, m_ConstantInt<0>()) &&
-               match(FalseVal, m_ConstantInt<-1>()))
-        Pred = CmpInst::getInversePredicate(ICI->getPredicate());
-      
-      if (Pred != CmpInst::BAD_ICMP_PREDICATE) {
-        // If we are just checking for a icmp eq of a single bit and zext'ing it
-        // to an integer, then shift the bit to the appropriate place and then
-        // cast to integer to avoid the comparison.
-        const APInt &Op1CV = CI->getValue();
-    
-        // sext (x <s  0) to i32 --> x>>s31      true if signbit set.
-        // sext (x >s -1) to i32 --> (x>>s31)^-1  true if signbit clear.
-        if ((Pred == ICmpInst::ICMP_SLT && Op1CV == 0) ||
-            (Pred == ICmpInst::ICMP_SGT && Op1CV.isAllOnesValue())) {
-          Value *In = ICI->getOperand(0);
-          Value *Sh = ConstantInt::get(In->getType(),
-                                       In->getType()->getScalarSizeInBits()-1);
-          In = InsertNewInstBefore(BinaryOperator::CreateAShr(In, Sh,
-                                                        In->getName()+".lobit"),
-                                   *ICI);
-          if (In->getType() != SI.getType())
-            In = CastInst::CreateIntegerCast(In, SI.getType(),
-                                             true/*SExt*/, "tmp", ICI);
-    
-          if (Pred == ICmpInst::ICMP_SGT)
-            In = InsertNewInstBefore(BinaryOperator::CreateNot(In,
-                                       In->getName()+".not"), *ICI);
-    
-          return ReplaceInstUsesWith(SI, In);
-        }
-      }
     }
 
   if (CmpLHS == TrueVal && CmpRHS == FalseVal) {
@@ -516,16 +478,25 @@
   if (ConstantInt *TrueValC = dyn_cast<ConstantInt>(TrueVal))
     if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal)) {
       // select C, 1, 0 -> zext C to int
-      if (FalseValC->isZero() && TrueValC->getValue() == 1) {
-        return CastInst::Create(Instruction::ZExt, CondVal, SI.getType());
-      } else if (TrueValC->isZero() && FalseValC->getValue() == 1) {
-        // select C, 0, 1 -> zext !C to int
-        Value *NotCond =
-          InsertNewInstBefore(BinaryOperator::CreateNot(CondVal,
-                                               "not."+CondVal->getName()), SI);
-        return CastInst::Create(Instruction::ZExt, NotCond, SI.getType());
+      if (FalseValC->isZero() && TrueValC->getValue() == 1)
+        return new ZExtInst(CondVal, SI.getType());
+
+      // select C, -1, 0 -> sext C to int
+      if (FalseValC->isZero() && TrueValC->isAllOnesValue())
+        return new SExtInst(CondVal, SI.getType());
+      
+      // select C, 0, 1 -> zext !C to int
+      if (TrueValC->isZero() && FalseValC->getValue() == 1) {
+        Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
+        return new ZExtInst(NotCond, SI.getType());
       }
 
+      // select C, 0, -1 -> sext !C to int
+      if (TrueValC->isZero() && FalseValC->isAllOnesValue()) {
+        Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
+        return new SExtInst(NotCond, SI.getType());
+      }
+      
       if (ICmpInst *IC = dyn_cast<ICmpInst>(SI.getCondition())) {
         // If one of the constants is zero (we know they can't both be) and we
         // have an icmp instruction with zero, and we have an 'and' with the
@@ -547,8 +518,7 @@
                 ShouldNotVal ^= IC->getPredicate() == ICmpInst::ICMP_NE;
                 Value *V = ICA;
                 if (ShouldNotVal)
-                  V = InsertNewInstBefore(BinaryOperator::Create(
-                                  Instruction::Xor, V, ICA->getOperand(1)), SI);
+                  V = Builder->CreateXor(V, ICA->getOperand(1));
                 return ReplaceInstUsesWith(SI, V);
               }
       }

Modified: llvm/trunk/test/Transforms/InstCombine/logical-select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/logical-select.ll?rev=94339&r1=94338&r2=94339&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/logical-select.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/logical-select.ll Sat Jan 23 18:09:49 2010
@@ -1,7 +1,4 @@
-; RUN: opt < %s -instcombine -S > %t
-; RUN: grep select %t | count 5
-; RUN: not grep and %t
-; RUN: not grep or %t
+; RUN: opt < %s -instcombine -S > FileCheck %s
 
 define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
   %e = icmp slt i32 %a, %b
@@ -11,6 +8,9 @@
   %i = and i32 %d, %h
   %j = or i32 %g, %i
   ret i32 %j
+; CHECK: %e = icmp slt i32 %a, %b
+; CHECK: %j = select i1 %e, i32 %c, i32 %d
+; CHECK: ret i32 %j
 }
 define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
   %e = icmp slt i32 %a, %b
@@ -20,6 +20,9 @@
   %i = and i32 %d, %h
   %j = or i32 %i, %g
   ret i32 %j
+; CHECK: %e = icmp slt i32 %a, %b
+; CHECK: %j = select i1 %e, i32 %c, i32 %d
+; CHECK: ret i32 %j
 }
 define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
 entry:
@@ -30,6 +33,9 @@
   %2 = and i32 %not, %d
   %3 = or i32 %1, %2
   ret i32 %3
+; CHECK: %0 = icmp slt i32 %a, %b
+; CHECK: %1 = select i1 %0, i32 %c, i32 %d
+; CHECK: ret i32 %1
 }
 define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
 entry:
@@ -40,6 +46,9 @@
   %2 = and i32 %iftmp, %d
   %3 = or i32 %1, %2
   ret i32 %3
+; CHECK: %0 = icmp slt i32 %a, %b
+; CHECK: %1 = select i1 %0, i32 %c, i32 %d
+; CHECK: ret i32 %1
 }
 
 define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
@@ -51,4 +60,7 @@
   %2 = and i32 %not, %d
   %3 = or i32 %1, %2
   ret i32 %3
+; CHECK: %0 = icmp slt i32 %a, %b
+; CHECK: %1 = select i1 %0, i32 %c, i32 %d
+; CHECK: ret i32 %1
 }





More information about the llvm-commits mailing list