[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner lattner at cs.uiuc.edu
Wed May 4 12:10:43 PDT 2005



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.333 -> 1.334
---
Log message:

Instcombine: cast (X != 0) to int, cast (X == 1) to int  -> X iff X has only the low bit set.

This implements set.ll:test20.

This triggers 2x on povray, 9x on mesa, 11x on gcc, 2x on crafty, 1x on eon,
6x on perlbmk and 11x on m88ksim.

It allows us to compile these two functions into the same code:

struct s { unsigned int bit : 1; };
unsigned foo(struct s *p) {
  if (p->bit)
    return 1;
  else
    return 0;
}
unsigned bar(struct s *p) { return p->bit; }



---
Diffs of the changes:  (+25 -3)

 InstructionCombining.cpp |   28 +++++++++++++++++++++++++---
 1 files changed, 25 insertions(+), 3 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.333 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.334
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.333	Sat Apr 30 23:42:15 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Wed May  4 14:10:26 2005
@@ -3553,9 +3553,30 @@
           return new ShiftInst(Instruction::Shl, Op0c, Op1);
         }
         break;
+      case Instruction::SetNE:
+      case Instruction::SetEQ:
+        // We if we are just checking for a seteq of a single bit and casting it
+        // to an integer.  If so, shift the bit to the appropriate place then
+        // cast to integer to avoid the comparison.
+        if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
+          // cast (X != 0) to int, cast (X == 1) to int  -> X iff X has only the
+          // low bit set.
+          bool isSetNE = SrcI->getOpcode() == Instruction::SetNE;
+          if ((isSetNE && Op1C->getRawValue() == 0) ||
+              (!isSetNE && Op1C->getRawValue() == 1)) {
+            Constant *Not1 = 
+              ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
+            if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
+              if (CI.getType() == Op0->getType())
+                return ReplaceInstUsesWith(CI, Op0);
+              else
+                return new CastInst(Op0, CI.getType());
+            }
+          }
+        }
+        break;
       }
     }
-
   return 0;
 }
 
@@ -4603,8 +4624,9 @@
       // Now that I is pointing to the first non-allocation-inst in the block,
       // insert our getelementptr instruction...
       //
-      std::vector<Value*> Idx(2, Constant::getNullValue(Type::IntTy));
-      Value *V = new GetElementPtrInst(New, Idx, New->getName()+".sub", It);
+      Value *NullIdx = Constant::getNullValue(Type::IntTy);
+      Value *V = new GetElementPtrInst(New, NullIdx, NullIdx,
+                                       New->getName()+".sub", It);
 
       // Now make everything use the getelementptr instead of the original
       // allocation.






More information about the llvm-commits mailing list