Teach the transformation that moves binary operators around selects to preserve
authorNick Lewycky <nicholas@mxc.ca>
Sun, 27 Mar 2011 19:51:23 +0000 (19:51 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Sun, 27 Mar 2011 19:51:23 +0000 (19:51 +0000)
the subclass optional data.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128388 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineSelect.cpp
test/Transforms/InstCombine/select.ll

index 50ea79f9b8c9e14ac01df1ede18c0b7a946c9d78..02f1ae78063213522cac9d650681f47a8556cf3e 100644 (file)
@@ -214,7 +214,7 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal,
         unsigned OpToFold = 0;
         if ((SFO & 1) && FalseVal == TVI->getOperand(0)) {
           OpToFold = 1;
-        } else  if ((SFO & 2) && FalseVal == TVI->getOperand(1)) {
+        } else if ((SFO & 2) && FalseVal == TVI->getOperand(1)) {
           OpToFold = 2;
         }
 
@@ -227,9 +227,16 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal,
             Instruction *NewSel = SelectInst::Create(SI.getCondition(), OOp, C);
             InsertNewInstBefore(NewSel, SI);
             NewSel->takeName(TVI);
-            if (BinaryOperator *BO = dyn_cast<BinaryOperator>(TVI))
-              return BinaryOperator::Create(BO->getOpcode(), FalseVal, NewSel);
-            llvm_unreachable("Unknown instruction!!");
+           BinaryOperator *TVI_BO = cast<BinaryOperator>(TVI);
+            BinaryOperator *BO = BinaryOperator::Create(TVI_BO->getOpcode(),
+                                                        FalseVal, NewSel);
+           if (isa<PossiblyExactOperator>(BO))
+             BO->setIsExact(TVI_BO->isExact());
+           if (isa<OverflowingBinaryOperator>(BO)) {
+             BO->setHasNoUnsignedWrap(TVI_BO->hasNoUnsignedWrap());
+             BO->setHasNoSignedWrap(TVI_BO->hasNoSignedWrap());
+           }
+           return BO;
           }
         }
       }
@@ -243,7 +250,7 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal,
         unsigned OpToFold = 0;
         if ((SFO & 1) && TrueVal == FVI->getOperand(0)) {
           OpToFold = 1;
-        } else  if ((SFO & 2) && TrueVal == FVI->getOperand(1)) {
+        } else if ((SFO & 2) && TrueVal == FVI->getOperand(1)) {
           OpToFold = 2;
         }
 
@@ -256,9 +263,16 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal,
             Instruction *NewSel = SelectInst::Create(SI.getCondition(), C, OOp);
             InsertNewInstBefore(NewSel, SI);
             NewSel->takeName(FVI);
-            if (BinaryOperator *BO = dyn_cast<BinaryOperator>(FVI))
-              return BinaryOperator::Create(BO->getOpcode(), TrueVal, NewSel);
-            llvm_unreachable("Unknown instruction!!");
+            BinaryOperator *FVI_BO = cast<BinaryOperator>(FVI);
+            BinaryOperator *BO = BinaryOperator::Create(FVI_BO->getOpcode(),
+                                                        TrueVal, NewSel);
+           if (isa<PossiblyExactOperator>(BO))
+             BO->setIsExact(FVI_BO->isExact());
+           if (isa<OverflowingBinaryOperator>(BO)) {
+             BO->setHasNoUnsignedWrap(FVI_BO->hasNoUnsignedWrap());
+             BO->setHasNoSignedWrap(FVI_BO->hasNoSignedWrap());
+           }
+           return BO;
           }
         }
       }
index 40237ae31058459bf9b8ff5d75244aba6876edd3..39259078b877d236c95d134f1783ed12bc630832 100644 (file)
@@ -737,3 +737,15 @@ define i32 @test54(i32 %X, i32 %Y) {
 ; CHECK: zext 
 ; CHECK: ret
 }
+
+define i1 @test55(i1 %X, i32 %Y, i32 %Z) {
+  %A = ashr exact i32 %Y, %Z
+  %B = select i1 %X, i32 %Y, i32 %A
+  %C = icmp eq i32 %B, 0
+  ret i1 %C
+; CHECK: @test55
+; CHECK-NOT: ashr
+; CHECK-NOT: select
+; CHECK: icmp eq
+; CHECK: ret i1
+}