[DAG] Use value tracking to detect or_disjoint patterns and add a add_like pattern matcher (#187478)
Extend the generic or_disjoint pattern to call haveNoCommonBitsSet, this allows us to remove the similar x86 or_is_add pattern, use or_disjoint directly and merge some add/or_is_add matching patterns to use a add_like wrapper pattern instead
This commit is contained in:
parent
4199bb1a81
commit
d049eef4b5
@ -1310,13 +1310,18 @@ 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();
|
||||
return N->getFlags().hasDisjoint() ||
|
||||
CurDAG->haveNoCommonBitsSet(N->getOperand(0), N->getOperand(1));
|
||||
}]> {
|
||||
let GISelPredicateCode = [{
|
||||
return MI.getFlag(MachineInstr::Disjoint);
|
||||
}];
|
||||
}
|
||||
|
||||
def add_like : PatFrags<(ops node:$lhs, node:$rhs),
|
||||
[(add node:$lhs, node:$rhs),
|
||||
(or_disjoint node:$lhs, node:$rhs)]>;
|
||||
|
||||
def xor_like : PatFrags<(ops node:$lhs, node:$rhs),
|
||||
[(xor node:$lhs, node:$rhs),
|
||||
(or_disjoint node:$lhs, node:$rhs)]>;
|
||||
|
||||
@ -1539,33 +1539,33 @@ let isConvertibleToThreeAddress = 1, isPseudo = 1,
|
||||
let isCommutable = 1 in {
|
||||
def ADD8rr_DB : I<0, Pseudo, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
|
||||
"", // orb/addb REG, REG
|
||||
[(set GR8:$dst, (or_is_add GR8:$src1, GR8:$src2))]>;
|
||||
[(set GR8:$dst, (or_disjoint GR8:$src1, GR8:$src2))]>;
|
||||
def ADD16rr_DB : I<0, Pseudo, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
|
||||
"", // orw/addw REG, REG
|
||||
[(set GR16:$dst, (or_is_add GR16:$src1, GR16:$src2))]>;
|
||||
[(set GR16:$dst, (or_disjoint GR16:$src1, GR16:$src2))]>;
|
||||
def ADD32rr_DB : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
|
||||
"", // orl/addl REG, REG
|
||||
[(set GR32:$dst, (or_is_add GR32:$src1, GR32:$src2))]>;
|
||||
[(set GR32:$dst, (or_disjoint GR32:$src1, GR32:$src2))]>;
|
||||
def ADD64rr_DB : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
|
||||
"", // orq/addq REG, REG
|
||||
[(set GR64:$dst, (or_is_add GR64:$src1, GR64:$src2))]>;
|
||||
[(set GR64:$dst, (or_disjoint GR64:$src1, GR64:$src2))]>;
|
||||
} // isCommutable
|
||||
|
||||
def ADD8ri_DB : I<0, Pseudo,
|
||||
(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
|
||||
"", // orb/addb REG, imm8
|
||||
[(set GR8:$dst, (or_is_add GR8:$src1, imm:$src2))]>;
|
||||
[(set GR8:$dst, (or_disjoint GR8:$src1, imm:$src2))]>;
|
||||
def ADD16ri_DB : I<0, Pseudo, (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
|
||||
"", // orw/addw REG, imm
|
||||
[(set GR16:$dst, (or_is_add GR16:$src1, imm:$src2))]>;
|
||||
[(set GR16:$dst, (or_disjoint GR16:$src1, imm:$src2))]>;
|
||||
def ADD32ri_DB : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
|
||||
"", // orl/addl REG, imm
|
||||
[(set GR32:$dst, (or_is_add GR32:$src1, imm:$src2))]>;
|
||||
[(set GR32:$dst, (or_disjoint GR32:$src1, imm:$src2))]>;
|
||||
def ADD64ri32_DB : I<0, Pseudo,
|
||||
(outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
|
||||
"", // orq/addq REG, imm
|
||||
[(set GR64:$dst, (or_is_add GR64:$src1,
|
||||
i64immSExt32:$src2))]>;
|
||||
[(set GR64:$dst, (or_disjoint GR64:$src1,
|
||||
i64immSExt32:$src2))]>;
|
||||
}
|
||||
} // AddedComplexity, SchedRW
|
||||
|
||||
@ -2230,9 +2230,9 @@ multiclass EFLAGSDefiningPats<string suffix, Predicate PredNDD, Predicate PredND
|
||||
// Increment/Decrement reg.
|
||||
// Do not make INC/DEC if it is slow
|
||||
let Predicates = [UseIncDec, PredNDD] in {
|
||||
def : Pat<(add GR8:$src, 1), (!cast<Instruction>(INC8r#suffix) GR8:$src)>;
|
||||
def : Pat<(add GR16:$src, 1), (!cast<Instruction>(INC16r#suffix) GR16:$src)>;
|
||||
def : Pat<(add GR32:$src, 1), (!cast<Instruction>(INC32r#suffix) GR32:$src)>;
|
||||
def : Pat<(add_like GR8:$src, 1), (!cast<Instruction>(INC8r#suffix) GR8:$src)>;
|
||||
def : Pat<(add_like GR16:$src, 1), (!cast<Instruction>(INC16r#suffix) GR16:$src)>;
|
||||
def : Pat<(add_like GR32:$src, 1), (!cast<Instruction>(INC32r#suffix) GR32:$src)>;
|
||||
def : Pat<(add GR8:$src, -1), (!cast<Instruction>(DEC8r#suffix) GR8:$src)>;
|
||||
def : Pat<(add GR16:$src, -1), (!cast<Instruction>(DEC16r#suffix) GR16:$src)>;
|
||||
def : Pat<(add GR32:$src, -1), (!cast<Instruction>(DEC32r#suffix) GR32:$src)>;
|
||||
@ -2243,18 +2243,13 @@ multiclass EFLAGSDefiningPats<string suffix, Predicate PredNDD, Predicate PredND
|
||||
def : Pat<(X86sub_flag_nocf GR8:$src, -1), (!cast<Instruction>(INC8r#suffix) GR8:$src)>;
|
||||
def : Pat<(X86sub_flag_nocf GR16:$src, -1), (!cast<Instruction>(INC16r#suffix) GR16:$src)>;
|
||||
def : Pat<(X86sub_flag_nocf GR32:$src, -1), (!cast<Instruction>(INC32r#suffix) GR32:$src)>;
|
||||
|
||||
def : Pat<(or_is_add GR8:$src, 1), (!cast<Instruction>(INC8r#suffix) GR8:$src)>;
|
||||
def : Pat<(or_is_add GR16:$src, 1), (!cast<Instruction>(INC16r#suffix) GR16:$src)>;
|
||||
def : Pat<(or_is_add GR32:$src, 1), (!cast<Instruction>(INC32r#suffix) GR32:$src)>;
|
||||
}
|
||||
|
||||
let Predicates = [UseIncDec, PredNDDI] in {
|
||||
def : Pat<(add GR64:$src, 1), (!cast<Instruction>(INC64r#suffix) GR64:$src)>;
|
||||
def : Pat<(add_like GR64:$src, 1), (!cast<Instruction>(INC64r#suffix) GR64:$src)>;
|
||||
def : Pat<(add GR64:$src, -1), (!cast<Instruction>(DEC64r#suffix) GR64:$src)>;
|
||||
def : Pat<(X86add_flag_nocf GR64:$src, -1), (!cast<Instruction>(DEC64r#suffix) GR64:$src)>;
|
||||
def : Pat<(X86sub_flag_nocf GR64:$src, -1), (!cast<Instruction>(INC64r#suffix) GR64:$src)>;
|
||||
def : Pat<(or_is_add GR64:$src, 1), (!cast<Instruction>(INC64r#suffix) GR64:$src)>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -850,16 +850,6 @@ def def32 : PatLeaf<(i32 GR32:$src), [{
|
||||
(!N->getOperand(0).isUndef() && !isa<ConstantSDNode>(N->getOperand(0))));
|
||||
}]>;
|
||||
|
||||
// Treat an 'or' node is as an 'add' if the or'ed bits are known to be zero.
|
||||
def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
|
||||
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
|
||||
return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue());
|
||||
|
||||
KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0);
|
||||
KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0);
|
||||
return (~Known0.Zero & ~Known1.Zero) == 0;
|
||||
}]>;
|
||||
|
||||
def shiftMask8 : PatFrag<(ops node:$lhs), (and node:$lhs, imm), [{
|
||||
return isUnneededShiftMask(N, 3);
|
||||
}]>;
|
||||
|
||||
@ -191,11 +191,12 @@ define i32 @not_a_masked_merge4(i32 %a0, i32 %a1, i32 %a2) {
|
||||
define i32 @masked_merge_no_transform0(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {
|
||||
; NOBMI-LABEL: masked_merge_no_transform0:
|
||||
; NOBMI: # %bb.0:
|
||||
; NOBMI-NEXT: movl %edi, %eax
|
||||
; NOBMI-NEXT: # kill: def $esi killed $esi def $rsi
|
||||
; NOBMI-NEXT: # kill: def $edi killed $edi def $rdi
|
||||
; NOBMI-NEXT: andl %edi, %esi
|
||||
; NOBMI-NEXT: notl %eax
|
||||
; NOBMI-NEXT: andl %edx, %eax
|
||||
; NOBMI-NEXT: orl %esi, %eax
|
||||
; NOBMI-NEXT: notl %edi
|
||||
; NOBMI-NEXT: andl %edx, %edi
|
||||
; NOBMI-NEXT: leal (%rdi,%rsi), %eax
|
||||
; NOBMI-NEXT: movl %esi, (%rcx)
|
||||
; NOBMI-NEXT: retq
|
||||
;
|
||||
@ -218,11 +219,12 @@ define i32 @masked_merge_no_transform0(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {
|
||||
define i32 @masked_merge_no_transform1(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {
|
||||
; NOBMI-LABEL: masked_merge_no_transform1:
|
||||
; NOBMI: # %bb.0:
|
||||
; NOBMI-NEXT: movl %edx, %eax
|
||||
; NOBMI-NEXT: # kill: def $edx killed $edx def $rdx
|
||||
; NOBMI-NEXT: # kill: def $esi killed $esi def $rsi
|
||||
; NOBMI-NEXT: andl %edi, %esi
|
||||
; NOBMI-NEXT: notl %edi
|
||||
; NOBMI-NEXT: andl %edi, %eax
|
||||
; NOBMI-NEXT: orl %esi, %eax
|
||||
; NOBMI-NEXT: andl %edi, %edx
|
||||
; NOBMI-NEXT: leal (%rdx,%rsi), %eax
|
||||
; NOBMI-NEXT: movl %edi, (%rcx)
|
||||
; NOBMI-NEXT: retq
|
||||
;
|
||||
@ -246,20 +248,21 @@ define i32 @masked_merge_no_transform1(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {
|
||||
define i32 @masked_merge_no_transform2(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {
|
||||
; NOBMI-LABEL: masked_merge_no_transform2:
|
||||
; NOBMI: # %bb.0:
|
||||
; NOBMI-NEXT: movl %esi, %eax
|
||||
; NOBMI-NEXT: andl %edi, %eax
|
||||
; NOBMI-NEXT: # kill: def $esi killed $esi def $rsi
|
||||
; NOBMI-NEXT: # kill: def $edi killed $edi def $rdi
|
||||
; NOBMI-NEXT: andl %edi, %esi
|
||||
; NOBMI-NEXT: notl %edi
|
||||
; NOBMI-NEXT: andl %edx, %edi
|
||||
; NOBMI-NEXT: orl %edi, %eax
|
||||
; NOBMI-NEXT: leal (%rsi,%rdi), %eax
|
||||
; NOBMI-NEXT: movl %edi, (%rcx)
|
||||
; NOBMI-NEXT: retq
|
||||
;
|
||||
; BMI-LABEL: masked_merge_no_transform2:
|
||||
; BMI: # %bb.0:
|
||||
; BMI-NEXT: movl %esi, %eax
|
||||
; BMI-NEXT: andl %edi, %eax
|
||||
; BMI-NEXT: # kill: def $esi killed $esi def $rsi
|
||||
; BMI-NEXT: andl %edi, %esi
|
||||
; BMI-NEXT: andnl %edx, %edi, %edx
|
||||
; BMI-NEXT: orl %edx, %eax
|
||||
; BMI-NEXT: leal (%rsi,%rdx), %eax
|
||||
; BMI-NEXT: movl %edx, (%rcx)
|
||||
; BMI-NEXT: retq
|
||||
%and0 = and i32 %a0, %a1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user