Skip to content

Commit 2d424e6

Browse files
authored
[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.
1 parent 16b8fb1 commit 2d424e6

File tree

5 files changed

+37
-1
lines changed

5 files changed

+37
-1
lines changed

llvm/include/llvm/Target/TargetSelectionDAG.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,19 @@ def not : PatFrag<(ops node:$in), (xor node:$in, -1)>;
11401140
def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>;
11411141
def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
11421142

1143+
def or_disjoint : PatFrag<(ops node:$lhs, node:$rhs),
1144+
(or node:$lhs, node:$rhs), [{
1145+
return N->getFlags().hasDisjoint();
1146+
}]> {
1147+
let GISelPredicateCode = [{
1148+
return MI.getFlag(MachineInstr::Disjoint);
1149+
}];
1150+
}
1151+
1152+
def xor_like : PatFrags<(ops node:$lhs, node:$rhs),
1153+
[(xor node:$lhs, node:$rhs),
1154+
(or_disjoint node:$lhs, node:$rhs)]>;
1155+
11431156
def zanyext : PatFrags<(ops node:$op),
11441157
[(zext node:$op),
11451158
(anyext node:$op)]>;

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3118,7 +3118,7 @@ defm AND : LogicalReg<0b00, 0, "and", and>;
31183118
defm BIC : LogicalReg<0b00, 1, "bic",
31193119
BinOpFrag<(and node:$LHS, (not node:$RHS))>, 3>;
31203120
defm EON : LogicalReg<0b10, 1, "eon",
3121-
BinOpFrag<(not (xor node:$LHS, node:$RHS))>>;
3121+
BinOpFrag<(not (xor_like node:$LHS, node:$RHS))>>;
31223122
defm EOR : LogicalReg<0b10, 0, "eor", xor>;
31233123
defm ORN : LogicalReg<0b01, 1, "orn",
31243124
BinOpFrag<(or node:$LHS, (not node:$RHS))>>;

llvm/test/CodeGen/AArch64/eon.ll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,24 @@ entry:
3030
%shl2 = shl i64 %xor, %xor1
3131
ret i64 %shl2
3232
}
33+
34+
; Check that eon is generated if the xor is a disjoint or.
35+
define i64 @disjoint_or(i64 %a, i64 %b) {
36+
; CHECK-LABEL: disjoint_or:
37+
; CHECK: eon
38+
; CHECK: ret
39+
%or = or disjoint i64 %a, %b
40+
%eon = xor i64 %or, -1
41+
ret i64 %eon
42+
}
43+
44+
; Check that eon is *not* generated if the or is not disjoint.
45+
define i64 @normal_or(i64 %a, i64 %b) {
46+
; CHECK-LABEL: normal_or:
47+
; CHECK: orr
48+
; CHECK: mvn
49+
; CHECK: ret
50+
%or = or i64 %a, %b
51+
%not = xor i64 %or, -1
52+
ret i64 %not
53+
}

llvm/test/TableGen/GlobalISelEmitter/CustomPredicate.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// CHECK-NEXT: enum {
77
// CHECK-NEXT: GICXXPred_MI_Predicate_and_or_pat = GICXXPred_Invalid + 1,
88
// CHECK-NEXT: GICXXPred_MI_Predicate_mul_pat,
9+
// CHECK-NEXT: GICXXPred_MI_Predicate_or_disjoint,
910
// CHECK-NEXT: GICXXPred_MI_Predicate_or_oneuse,
1011
// CHECK-NEXT: GICXXPred_MI_Predicate_patfrags_test_pat,
1112
// CHECK-NEXT: GICXXPred_MI_Predicate_sub3_pat,

llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
156156
// CHECK-LABEL: // PatFrag predicates.
157157
// CHECK-NEXT: enum {
158158
// CHECK-NEXT: GICXXPred_MI_Predicate_frag = GICXXPred_Invalid + 1,
159+
// CHECK-NEXT: GICXXPred_MI_Predicate_or_disjoint,
159160
// CHECK-NEXT: };
160161

161162
// CHECK-LABEL: // PatFrag predicates.

0 commit comments

Comments
 (0)