[AArch64] Lower disjoint_or+not to eon. (#147279)

A disjoint OR can be transformed to an EOR.

We already lower EOR+NOT to EON, but not DisjointOR+NOT.
This commit is contained in:
Ricardo Jesus 2025-07-09 08:38:16 +01:00 committed by GitHub
parent 16b8fb1b4a
commit 2d424e6333
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 37 additions and 1 deletions

View File

@ -1140,6 +1140,19 @@ def not : PatFrag<(ops node:$in), (xor node:$in, -1)>;
def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>;
def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
def or_disjoint : PatFrag<(ops node:$lhs, node:$rhs),
(or node:$lhs, node:$rhs), [{
return N->getFlags().hasDisjoint();
}]> {
let GISelPredicateCode = [{
return MI.getFlag(MachineInstr::Disjoint);
}];
}
def xor_like : PatFrags<(ops node:$lhs, node:$rhs),
[(xor node:$lhs, node:$rhs),
(or_disjoint node:$lhs, node:$rhs)]>;
def zanyext : PatFrags<(ops node:$op),
[(zext node:$op),
(anyext node:$op)]>;

View File

@ -3118,7 +3118,7 @@ defm AND : LogicalReg<0b00, 0, "and", and>;
defm BIC : LogicalReg<0b00, 1, "bic",
BinOpFrag<(and node:$LHS, (not node:$RHS))>, 3>;
defm EON : LogicalReg<0b10, 1, "eon",
BinOpFrag<(not (xor node:$LHS, node:$RHS))>>;
BinOpFrag<(not (xor_like node:$LHS, node:$RHS))>>;
defm EOR : LogicalReg<0b10, 0, "eor", xor>;
defm ORN : LogicalReg<0b01, 1, "orn",
BinOpFrag<(or node:$LHS, (not node:$RHS))>>;

View File

@ -30,3 +30,24 @@ entry:
%shl2 = shl i64 %xor, %xor1
ret i64 %shl2
}
; Check that eon is generated if the xor is a disjoint or.
define i64 @disjoint_or(i64 %a, i64 %b) {
; CHECK-LABEL: disjoint_or:
; CHECK: eon
; CHECK: ret
%or = or disjoint i64 %a, %b
%eon = xor i64 %or, -1
ret i64 %eon
}
; Check that eon is *not* generated if the or is not disjoint.
define i64 @normal_or(i64 %a, i64 %b) {
; CHECK-LABEL: normal_or:
; CHECK: orr
; CHECK: mvn
; CHECK: ret
%or = or i64 %a, %b
%not = xor i64 %or, -1
ret i64 %not
}

View File

@ -6,6 +6,7 @@
// CHECK-NEXT: enum {
// CHECK-NEXT: GICXXPred_MI_Predicate_and_or_pat = GICXXPred_Invalid + 1,
// CHECK-NEXT: GICXXPred_MI_Predicate_mul_pat,
// CHECK-NEXT: GICXXPred_MI_Predicate_or_disjoint,
// CHECK-NEXT: GICXXPred_MI_Predicate_or_oneuse,
// CHECK-NEXT: GICXXPred_MI_Predicate_patfrags_test_pat,
// CHECK-NEXT: GICXXPred_MI_Predicate_sub3_pat,

View File

@ -156,6 +156,7 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
// CHECK-LABEL: // PatFrag predicates.
// CHECK-NEXT: enum {
// CHECK-NEXT: GICXXPred_MI_Predicate_frag = GICXXPred_Invalid + 1,
// CHECK-NEXT: GICXXPred_MI_Predicate_or_disjoint,
// CHECK-NEXT: };
// CHECK-LABEL: // PatFrag predicates.