Implement select.ll:test[3-6]
authorChris Lattner <sabre@nondot.org>
Tue, 30 Mar 2004 19:37:13 +0000 (19:37 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 30 Mar 2004 19:37:13 +0000 (19:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12544 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index 9b91705110d0966423ba3f84eadf0dd8be34581f..13c6b26db1b64f390dab88a46d075ce909a8ddfc 100644 (file)
@@ -1994,14 +1994,42 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
 }
 
 Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
-  if (ConstantBool *C = dyn_cast<ConstantBool>(SI.getCondition()))
+  Value *CondVal = SI.getCondition();
+  Value *TrueVal = SI.getTrueValue();
+  Value *FalseVal = SI.getFalseValue();
+
+  // select true, X, Y  -> X
+  // select false, X, Y -> Y
+  if (ConstantBool *C = dyn_cast<ConstantBool>(CondVal))
     if (C == ConstantBool::True)
-      return ReplaceInstUsesWith(SI, SI.getTrueValue());
+      return ReplaceInstUsesWith(SI, TrueVal);
     else {
       assert(C == ConstantBool::False);
-      return ReplaceInstUsesWith(SI, SI.getFalseValue());
+      return ReplaceInstUsesWith(SI, FalseVal);
+    }
+
+  // select C, X, X -> X
+  if (TrueVal == FalseVal)
+    return ReplaceInstUsesWith(SI, TrueVal);
+
+  // Selecting between two constants?
+  if (Constant *TrueValC = dyn_cast<Constant>(TrueVal))
+    if (Constant *FalseValC = dyn_cast<Constant>(FalseVal)) {
+      if (SI.getType() == Type::BoolTy &&
+          isa<ConstantBool>(TrueValC) && isa<ConstantBool>(FalseValC)) {
+        // select C, true, false -> C
+        if (TrueValC == ConstantBool::True)
+          return ReplaceInstUsesWith(SI, CondVal);
+        // select C, false, true -> !C
+        return BinaryOperator::createNot(CondVal);
+      }
+      
+      // If the true constant is a 1 and the false is a zero, turn this into a
+      // cast from bool.
+      if (FalseValC->isNullValue() && isa<ConstantInt>(TrueValC) &&
+          cast<ConstantInt>(TrueValC)->getRawValue() == 1)
+        return new CastInst(CondVal, SI.getType());
     }
-  // Other transformations are possible!
 
   return 0;
 }