forked from OSchip/llvm-project
[InstCombine] Add general constant support to eq/ne icmp(add(X,C1),add(Y,C2)) -> icmp(add(X,C1-C2),Y) fold
A further extension for Issue #32161 For eq/ne comparisons - the sign mismatch and bounds constraints are redundant, so if the that fold fails, fallback and just fold the constants directly. https://alive2.llvm.org/ce/z/cdodNQ The loop rotation test change looks mostly benign - the backend doesn't seem to suffer? https://gcc.godbolt.org/z/dErMY78To Differential Revision: https://reviews.llvm.org/D121551
This commit is contained in:
parent
1df20fa8f5
commit
7e4cf582cf
|
@ -4134,6 +4134,13 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
|
|||
return new ICmpInst(Pred, A, NewAdd);
|
||||
}
|
||||
}
|
||||
Constant *Cst1, *Cst2;
|
||||
if (match(B, m_ImmConstant(Cst1)) && match(D, m_ImmConstant(Cst2)) &&
|
||||
ICmpInst::isEquality(Pred)) {
|
||||
Constant *Diff = ConstantExpr::getSub(Cst2, Cst1);
|
||||
Value *NewAdd = Builder.CreateAdd(C, Diff);
|
||||
return new ICmpInst(Pred, A, NewAdd);
|
||||
}
|
||||
}
|
||||
|
||||
// Analyze the case when either Op0 or Op1 is a sub instruction.
|
||||
|
|
|
@ -1565,9 +1565,8 @@ define <2 x i1> @icmp_add20_eq_add57_undef(<2 x i32> %x, <2 x i32> %y) {
|
|||
|
||||
define <2 x i1> @icmp_add20_eq_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @icmp_add20_eq_add57_vec_nonsplat(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 20, i32 19>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i32> [[Y:%.*]], <i32 57, i32 58>
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], [[TMP2]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], <i32 37, i32 39>
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
||||
;
|
||||
%1 = add <2 x i32> %x, <i32 20, i32 19>
|
||||
|
@ -1614,9 +1613,8 @@ define <2 x i1> @icmp_sub57_ne_sub20_vec_undef(<2 x i32> %x, <2 x i32> %y) {
|
|||
|
||||
define <2 x i1> @icmp_sub57_ne_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @icmp_sub57_ne_sub20_vec_nonsplat(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 -57, i32 -58>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i32> [[Y:%.*]], <i32 -20, i32 -21>
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[TMP2]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], <i32 37, i32 37>
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
||||
;
|
||||
%1 = add <2 x i32> %x, <i32 -57, i32 -58>
|
||||
|
|
|
@ -76,19 +76,21 @@ define void @_Z4loopi(i32 %width) {
|
|||
; ROTATE-NEXT: [[CMP:%.*]] = icmp slt i32 [[WIDTH:%.*]], 1
|
||||
; ROTATE-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[FOR_COND_PREHEADER:%.*]]
|
||||
; ROTATE: for.cond.preheader:
|
||||
; ROTATE-NEXT: [[SUB:%.*]] = add nsw i32 [[WIDTH]], -1
|
||||
; ROTATE-NEXT: [[CMP13_NOT:%.*]] = icmp eq i32 [[WIDTH]], 1
|
||||
; ROTATE-NEXT: br i1 [[CMP13_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]]
|
||||
; ROTATE-NEXT: br i1 [[CMP13_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
|
||||
; ROTATE: for.body.preheader:
|
||||
; ROTATE-NEXT: [[TMP0:%.*]] = add i32 [[WIDTH]], -2
|
||||
; ROTATE-NEXT: br label [[FOR_BODY:%.*]]
|
||||
; ROTATE: for.cond.cleanup:
|
||||
; ROTATE-NEXT: tail call void @f0()
|
||||
; ROTATE-NEXT: tail call void @f2()
|
||||
; ROTATE-NEXT: br label [[RETURN]]
|
||||
; ROTATE: for.body:
|
||||
; ROTATE-NEXT: [[I_04:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
|
||||
; ROTATE-NEXT: [[I_04:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
|
||||
; ROTATE-NEXT: tail call void @f0()
|
||||
; ROTATE-NEXT: tail call void @f1()
|
||||
; ROTATE-NEXT: [[INC]] = add nuw nsw i32 [[I_04]], 1
|
||||
; ROTATE-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[SUB]]
|
||||
; ROTATE-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[I_04]], [[TMP0]]
|
||||
; ROTATE-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]]
|
||||
; ROTATE: return:
|
||||
; ROTATE-NEXT: ret void
|
||||
|
|
Loading…
Reference in New Issue