+ //
+ // add (select X 0 (sub n A)) A ->
+ // select X A n
+ {
+ SelectInst *SI = dyn_cast<SelectInst>(LHS);
+ Value *Other = RHS;
+ if (!SI) {
+ SI = dyn_cast<SelectInst>(RHS);
+ Other = LHS;
+ }
+ if (SI) {
+ Value *TV = SI->getTrueValue();
+ Value *FV = SI->getFalseValue();
+ Value *A;
+
+ // Can we fold the add into the argument of the compare?
+ Value *Cond = SI->getCondition();
+ if (ICmpInst *IC = dyn_cast<ICmpInst>(Cond)) {
+ Value *ICOp0 = IC->getOperand(0);
+ Value *ICOp1 = IC->getOperand(1);
+ ConstantInt *C3, *C4;
+
+ // Check both arguments of the compare for a matching
subtract.
+ if (match(ICOp0, m_ConstantInt(C3)) && C3->getValue() ==
0 &&
+ match(ICOp1, m_Sub(m_ConstantInt(C4), m_Value(A))) &&
+ A == Other) {
+ // We managed to fold the add into the RHS of the select
condition.
+ Cond = new ICmpInst(IC->getPredicate(), A, C4, "asis",
SI);
+ } else if (match(ICOp1, m_ConstantInt(C3)) && C3->getValue
() == 0 &&
+ match(ICOp0, m_Sub(m_ConstantInt(C4), m_Value(A))) &&
+ A == Other) {
+ // We managed to fold the add into the LHS of the select
condition.
+ Cond = new ICmpInst(IC->getPredicate(), C4, A, "asis",
SI);
+ }
+ }
+
+ // Can we fold the add into the argument of the select?
+ // We check both true and false select arguments for a
matching subtract.
+ ConstantInt *C1, *C2;
+ if (match(FV, m_ConstantInt(C1)) && C1->getValue() == 0 &&
+ match(TV, m_Sub(m_ConstantInt(C2), m_Value(A))) &&
+ A == Other) {
+ // We managed to fold the add into the true select value,
+ // picking up a simplified condition, if available.
+ return new SelectInst(Cond, C2, A, "adselsub");
+ } else if (match(TV, m_ConstantInt(C1)) && C1->getValue() ==
0 &&
+ match(FV, m_Sub(m_ConstantInt(C2), m_Value(A))) &&
+ A == Other) {
+ // We managed to fold the add into the false select value,
+ // picking up a simplified condition, if available.
+ return new SelectInst(Cond, A, C2, "adselsub");
+ } else if (Cond != SI->getCondition()) {
+ // We only managed to fold the add into the select
condition.
+ SI->setOperand(0, Cond);
+ Changed = true;
+ }
+ }
+ }
return Changed ? &I : 0;
}
Added: llvm/trunk/test/Transforms/InstCombine/2007-12-18-
AddSelCmpSub.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/
InstCombine/2007-12-18-AddSelCmpSub.ll?rev=45158&view=auto
=====================================================================
=
========
--- llvm/trunk/test/Transforms/InstCombine/2007-12-18-
AddSelCmpSub.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/2007-12-18-
AddSelCmpSub.ll Tue Dec 18 03:34:41 2007
@@ -0,0 +1,38 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {sub}
+
+define i32 @foo(i32 %a) {
+entry:
+ %tmp15 = sub i32 99, %a ; <i32> [#uses=2]
+ %tmp16 = icmp slt i32 %tmp15, 0 ; <i1> [#uses=1]
+ %smax = select i1 %tmp16, i32 0, i32 %tmp15 ;
<i32> [#uses=1]
+ %tmp12 = add i32 %smax, %a ; <i32> [#uses=1]
+ %tmp13 = add i32 %tmp12, 1 ; <i32> [#uses=1]
+ ret i32 %tmp13
+}
+
+define i32 @bar(i32 %a) {
+entry:
+ %tmp15 = sub i32 99, %a ; <i32> [#uses=2]
+ %tmp16 = icmp slt i32 %tmp15, 0 ; <i1> [#uses=1]
+ %smax = select i1 %tmp16, i32 0, i32 %tmp15 ;
<i32> [#uses=1]
+ %tmp12 = add i32 %smax, %a ; <i32> [#uses=1]
+ ret i32 %tmp12
+}
+
+define i32 @baz(i32 %a) {
+entry:
+ %tmp15 = sub i32 99, %a ; <i32> [#uses=1]
+ %tmp16 = icmp slt i32 %tmp15, 0 ; <i1> [#uses=1]
+ %smax = select i1 %tmp16, i32 0, i32 42 ;
<i32> [#uses=1]
+ %tmp12 = add i32 %smax, %a ; <i32> [#uses=1]
+ ret i32 %tmp12
+}
+
+define i32 @fun(i32 %a) {
+entry:
+ %tmp15 = sub i32 99, %a ; <i32> [#uses=1]
+ %tmp16 = icmp slt i32 %a, 0 ; <i1> [#uses=1]
+ %smax = select i1 %tmp16, i32 0, i32 %tmp15 ;
<i32> [#uses=1]
+ %tmp12 = add i32 %smax, %a ; <i32> [#uses=1]
+ ret i32 %tmp12
+}
\ No newline at end of file
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits