mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	InstCombine: Don't take A-B<0 into A<B if A-B has other uses
This fixes PR22226. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226023 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -2686,33 +2686,35 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { | ||||
|         return Res; | ||||
|     } | ||||
|  | ||||
|     // (icmp ne/eq (sub A B) 0) -> (icmp ne/eq A, B) | ||||
|     if (I.isEquality() && CI->isZero() && | ||||
|         match(Op0, m_Sub(m_Value(A), m_Value(B)))) { | ||||
|       // (icmp cond A B) if cond is equality | ||||
|       return new ICmpInst(I.getPredicate(), A, B); | ||||
|     // The following transforms are only 'worth it' if the only user of the | ||||
|     // subtraction is the icmp. | ||||
|     if (Op0->hasOneUse()) { | ||||
|       // (icmp ne/eq (sub A B) 0) -> (icmp ne/eq A, B) | ||||
|       if (I.isEquality() && CI->isZero() && | ||||
|           match(Op0, m_Sub(m_Value(A), m_Value(B)))) | ||||
|         return new ICmpInst(I.getPredicate(), A, B); | ||||
|  | ||||
|       // (icmp sgt (sub nsw A B), -1) -> (icmp sge A, B) | ||||
|       if (I.getPredicate() == ICmpInst::ICMP_SGT && CI->isAllOnesValue() && | ||||
|           match(Op0, m_NSWSub(m_Value(A), m_Value(B)))) | ||||
|         return new ICmpInst(ICmpInst::ICMP_SGE, A, B); | ||||
|  | ||||
|       // (icmp sgt (sub nsw A B), 0) -> (icmp sgt A, B) | ||||
|       if (I.getPredicate() == ICmpInst::ICMP_SGT && CI->isZero() && | ||||
|           match(Op0, m_NSWSub(m_Value(A), m_Value(B)))) | ||||
|         return new ICmpInst(ICmpInst::ICMP_SGT, A, B); | ||||
|  | ||||
|       // (icmp slt (sub nsw A B), 0) -> (icmp slt A, B) | ||||
|       if (I.getPredicate() == ICmpInst::ICMP_SLT && CI->isZero() && | ||||
|           match(Op0, m_NSWSub(m_Value(A), m_Value(B)))) | ||||
|         return new ICmpInst(ICmpInst::ICMP_SLT, A, B); | ||||
|  | ||||
|       // (icmp slt (sub nsw A B), 1) -> (icmp sle A, B) | ||||
|       if (I.getPredicate() == ICmpInst::ICMP_SLT && CI->isOne() && | ||||
|           match(Op0, m_NSWSub(m_Value(A), m_Value(B)))) | ||||
|         return new ICmpInst(ICmpInst::ICMP_SLE, A, B); | ||||
|     } | ||||
|  | ||||
|     // (icmp sgt (sub nsw A B), -1) -> (icmp sge A, B) | ||||
|     if (I.getPredicate() == ICmpInst::ICMP_SGT && CI->isAllOnesValue() && | ||||
|         match(Op0, m_NSWSub(m_Value(A), m_Value(B)))) | ||||
|       return new ICmpInst(ICmpInst::ICMP_SGE, A, B); | ||||
|  | ||||
|     // (icmp sgt (sub nsw A B), 0) -> (icmp sgt A, B) | ||||
|     if (I.getPredicate() == ICmpInst::ICMP_SGT && CI->isZero() && | ||||
|         match(Op0, m_NSWSub(m_Value(A), m_Value(B)))) | ||||
|       return new ICmpInst(ICmpInst::ICMP_SGT, A, B); | ||||
|  | ||||
|     // (icmp slt (sub nsw A B), 0) -> (icmp slt A, B) | ||||
|     if (I.getPredicate() == ICmpInst::ICMP_SLT && CI->isZero() && | ||||
|         match(Op0, m_NSWSub(m_Value(A), m_Value(B)))) | ||||
|       return new ICmpInst(ICmpInst::ICMP_SLT, A, B); | ||||
|  | ||||
|     // (icmp slt (sub nsw A B), 1) -> (icmp sle A, B) | ||||
|     if (I.getPredicate() == ICmpInst::ICMP_SLT && CI->isOne() && | ||||
|         match(Op0, m_NSWSub(m_Value(A), m_Value(B)))) | ||||
|       return new ICmpInst(ICmpInst::ICMP_SLE, A, B); | ||||
|  | ||||
|     // If we have an icmp le or icmp ge instruction, turn it into the | ||||
|     // appropriate icmp lt or icmp gt instruction.  This allows us to rely on | ||||
|     // them being folded in the code below.  The SimplifyICmpInst code has | ||||
|   | ||||
| @@ -1558,3 +1558,18 @@ define i1 @f4(i64 %a, i64 %b) { | ||||
|   %v = icmp sle i64 %t, 0 | ||||
|   ret i1 %v | ||||
| } | ||||
|  | ||||
| ; CHECK-LABEL: @f5 | ||||
| ; CHECK: %[[cmp:.*]] = icmp slt i32 %[[sub:.*]], 0 | ||||
| ; CHECK: %[[neg:.*]] = sub nsw i32 0, %[[sub]] | ||||
| ; CHECK: %[[sel:.*]] = select i1 %[[cmp]], i32 %[[neg]], i32 %[[sub]] | ||||
| ; CHECK: ret i32 %[[sel]] | ||||
| define i32 @f5(i8 %a, i8 %b) { | ||||
|   %conv = zext i8 %a to i32 | ||||
|   %conv3 = zext i8 %b to i32 | ||||
|   %sub = sub nsw i32 %conv, %conv3 | ||||
|   %cmp4 = icmp slt i32 %sub, 0 | ||||
|   %sub7 = sub nsw i32 0, %sub | ||||
|   %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub | ||||
|   ret i32 %sub7.sub | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user