1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[InstCombine] Support non-splat vectors in icmp eq + add/sub fold

For the

    icmp eq (add X, C1), C2 => icmp eq X, C2-C1
    icmp eq (sub C1, X), C2 => icmp eq X, C1-C2

folds, this allows C1 to be non-splat and contain undefs.
C2 is still splat, due to the structure of the code.

This is to address the remaining part of the regression in D73411,
where demanded element analysis replaces some elements with undef.

Differential Revision: https://reviews.llvm.org/D73647
This commit is contained in:
Nikita Popov 2020-01-29 18:58:48 +01:00
parent bb0b9ff69f
commit 3f4dd6c98c
3 changed files with 11 additions and 18 deletions

View File

@ -2928,12 +2928,9 @@ Instruction *InstCombiner::foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,
break;
case Instruction::Add: {
// Replace ((add A, B) != C) with (A != C-B) if B & C are constants.
const APInt *BOC;
if (match(BOp1, m_APInt(BOC))) {
if (BO->hasOneUse()) {
Constant *SubC = ConstantExpr::getSub(RHS, cast<Constant>(BOp1));
return new ICmpInst(Pred, BOp0, SubC);
}
if (Constant *BOC = dyn_cast<Constant>(BOp1)) {
if (BO->hasOneUse())
return new ICmpInst(Pred, BOp0, ConstantExpr::getSub(RHS, BOC));
} else if (C.isNullValue()) {
// Replace ((add A, B) != 0) with (A != -B) if A or B is
// efficiently invertible, or if the add has just this one use.
@ -2963,11 +2960,11 @@ Instruction *InstCombiner::foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,
break;
case Instruction::Sub:
if (BO->hasOneUse()) {
const APInt *BOC;
if (match(BOp0, m_APInt(BOC))) {
// Only check for constant LHS here, as constant RHS will be canonicalized
// to add and use the fold above.
if (Constant *BOC = dyn_cast<Constant>(BOp0)) {
// Replace ((sub BOC, B) != C) with (B != BOC-C).
Constant *SubC = ConstantExpr::getSub(cast<Constant>(BOp0), RHS);
return new ICmpInst(Pred, BOp1, SubC);
return new ICmpInst(Pred, BOp1, ConstantExpr::getSub(BOC, RHS));
} else if (C.isNullValue()) {
// Replace ((sub A, B) != 0) with (A != B).
return new ICmpInst(Pred, BOp0, BOp1);

View File

@ -624,8 +624,7 @@ define void @bzip2(i8 %a, i8 %b, i8 %x) {
define <2 x i1> @icmp_eq_add_undef(<2 x i32> %a) {
; CHECK-LABEL: @icmp_eq_add_undef(
; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[A:%.*]], <i32 5, i32 undef>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[ADD]], <i32 10, i32 10>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 undef>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%add = add <2 x i32> %a, <i32 5, i32 undef>
@ -635,8 +634,7 @@ define <2 x i1> @icmp_eq_add_undef(<2 x i32> %a) {
define <2 x i1> @icmp_eq_add_non_splat(<2 x i32> %a) {
; CHECK-LABEL: @icmp_eq_add_non_splat(
; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[A:%.*]], <i32 5, i32 6>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[ADD]], <i32 10, i32 10>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 4>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%add = add <2 x i32> %a, <i32 5, i32 6>

View File

@ -146,8 +146,7 @@ define <2 x i1> @test_sub_255_Y_eq_255_vec(<2 x i8> %y) {
define <2 x i1> @icmp_eq_sub_undef(<2 x i32> %a) {
; CHECK-LABEL: @icmp_eq_sub_undef(
; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> <i32 15, i32 undef>, [[A:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[SUB]], <i32 10, i32 10>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 undef>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%sub = sub <2 x i32> <i32 15, i32 undef>, %a
@ -157,8 +156,7 @@ define <2 x i1> @icmp_eq_sub_undef(<2 x i32> %a) {
define <2 x i1> @icmp_eq_sub_non_splat(<2 x i32> %a) {
; CHECK-LABEL: @icmp_eq_sub_non_splat(
; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> <i32 15, i32 16>, [[A:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[SUB]], <i32 10, i32 10>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 6>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%sub = sub <2 x i32> <i32 15, i32 16>, %a