Skip to content

[SystemZ] Don't use FP Load and Test as comparisons to same reg #78074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 4 additions & 18 deletions llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,6 @@ static bool preservesValueOf(MachineInstr &MI, unsigned Reg) {
case SystemZ::LTR:
case SystemZ::LTGR:
case SystemZ::LTGFR:
case SystemZ::LER:
case SystemZ::LDR:
case SystemZ::LXR:
case SystemZ::LTEBR:
case SystemZ::LTDBR:
case SystemZ::LTXBR:
if (MI.getOperand(1).getReg() == Reg)
return true;
}
Expand Down Expand Up @@ -498,18 +492,10 @@ bool SystemZElimCompare::adjustCCMasksForInstr(

// Return true if Compare is a comparison against zero.
static bool isCompareZero(MachineInstr &Compare) {
switch (Compare.getOpcode()) {
case SystemZ::LTEBRCompare:
case SystemZ::LTDBRCompare:
case SystemZ::LTXBRCompare:
if (isLoadAndTestAsCmp(Compare))
return true;

default:
if (isLoadAndTestAsCmp(Compare))
return true;
return Compare.getNumExplicitOperands() == 2 &&
Compare.getOperand(1).isImm() && Compare.getOperand(1).getImm() == 0;
}
return Compare.getNumExplicitOperands() == 2 &&
Compare.getOperand(1).isImm() && Compare.getOperand(1).getImm() == 0;
}

// Try to optimize cases where comparison instruction Compare is testing
Expand Down Expand Up @@ -569,7 +555,7 @@ bool SystemZElimCompare::optimizeCompareZero(

// Also do a forward search to handle cases where an instruction after the
// compare can be converted, like
// LTEBRCompare %f0s, %f0s; %f2s = LER %f0s => LTEBRCompare %f2s, %f0s
// CGHI %r0d, 0; %r1d = LGR %r0d => LTGR %r1d, %r0d
auto MIRange = llvm::make_range(
std::next(MachineBasicBlock::iterator(&Compare)), MBB.end());
for (MachineInstr &MI : llvm::make_early_inc_range(MIRange)) {
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9437,11 +9437,11 @@ MachineBasicBlock *SystemZTargetLowering::EmitInstrWithCustomInserter(
return emitTransactionBegin(MI, MBB, SystemZ::TBEGIN, true);
case SystemZ::TBEGINC:
return emitTransactionBegin(MI, MBB, SystemZ::TBEGINC, true);
case SystemZ::LTEBRCompare_VecPseudo:
case SystemZ::LTEBRCompare_Pseudo:
return emitLoadAndTestCmp0(MI, MBB, SystemZ::LTEBR);
case SystemZ::LTDBRCompare_VecPseudo:
case SystemZ::LTDBRCompare_Pseudo:
return emitLoadAndTestCmp0(MI, MBB, SystemZ::LTDBR);
case SystemZ::LTXBRCompare_VecPseudo:
case SystemZ::LTXBRCompare_Pseudo:
return emitLoadAndTestCmp0(MI, MBB, SystemZ::LTXBR);

case SystemZ::PROBED_ALLOCA:
Expand Down
37 changes: 14 additions & 23 deletions llvm/lib/Target/SystemZ/SystemZInstrFP.td
Original file line number Diff line number Diff line change
Expand Up @@ -51,36 +51,27 @@ let isCodeGenOnly = 1 in
def LDR32 : UnaryRR<"ldr", 0x28, null_frag, FP32, FP32>;

// Moves between two floating-point registers that also set the condition
// codes.
// codes. Note that these instructions will turn SNaNs into QNaNs and should
// not be used for comparison if the result will be used afterwards.
let Uses = [FPC], mayRaiseFPException = 1,
Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0xF in {
defm LTEBR : LoadAndTestRRE<"ltebr", 0xB302, FP32>;
defm LTDBR : LoadAndTestRRE<"ltdbr", 0xB312, FP64>;
defm LTXBR : LoadAndTestRRE<"ltxbr", 0xB342, FP128>;
}
// Note that LTxBRCompare is not available if we have vector support,
// since load-and-test instructions will partially clobber the target
// (vector) register.
let Predicates = [FeatureNoVector] in {
defm : CompareZeroFP<LTEBRCompare, FP32>;
defm : CompareZeroFP<LTDBRCompare, FP64>;
defm : CompareZeroFP<LTXBRCompare, FP128>;
def LTEBR : UnaryRRE<"ltebr", 0xB302, null_frag, FP32, FP32>;
def LTDBR : UnaryRRE<"ltdbr", 0xB312, null_frag, FP64, FP64>;
def LTXBR : UnaryRRE<"ltxbr", 0xB342, null_frag, FP128, FP128>;
}

// Use a normal load-and-test for compare against zero in case of
// vector support (via a pseudo to simplify instruction selection).
// Use a load-and-test for compare against zero (via a pseudo to simplify
// instruction selection).
let Uses = [FPC], mayRaiseFPException = 1,
Defs = [CC], usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
def LTEBRCompare_VecPseudo : Pseudo<(outs), (ins FP32:$R1, FP32:$R2), []>;
def LTDBRCompare_VecPseudo : Pseudo<(outs), (ins FP64:$R1, FP64:$R2), []>;
def LTXBRCompare_VecPseudo : Pseudo<(outs), (ins FP128:$R1, FP128:$R2), []>;
}
let Predicates = [FeatureVector] in {
defm : CompareZeroFP<LTEBRCompare_VecPseudo, FP32>;
defm : CompareZeroFP<LTDBRCompare_VecPseudo, FP64>;
def LTEBRCompare_Pseudo : Pseudo<(outs), (ins FP32:$R1), []>;
def LTDBRCompare_Pseudo : Pseudo<(outs), (ins FP64:$R1), []>;
def LTXBRCompare_Pseudo : Pseudo<(outs), (ins FP128:$R1), []>;
}
let Predicates = [FeatureVector, FeatureNoVectorEnhancements1] in
defm : CompareZeroFP<LTXBRCompare_VecPseudo, FP128>;
defm : CompareZeroFP<LTEBRCompare_Pseudo, FP32>;
defm : CompareZeroFP<LTDBRCompare_Pseudo, FP64>;
let Predicates = [FeatureNoVectorEnhancements1] in
defm : CompareZeroFP<LTXBRCompare_Pseudo, FP128>;

// Moves between 64-bit integer and floating-point registers.
def LGDR : UnaryRRE<"lgdr", 0xB3CD, bitconvert, GR64, FP64>;
Expand Down
12 changes: 0 additions & 12 deletions llvm/lib/Target/SystemZ/SystemZInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -5036,18 +5036,6 @@ class BranchPreloadMII<string mnemonic, bits<8> opcode>
(ins imm32zx4:$M1, brtarget12bpp:$RI2, brtarget24bpp:$RI3),
mnemonic#"\t$M1, $RI2, $RI3", []>;

// A floating-point load-and test operation. Create both a normal unary
// operation and one that acts as a comparison against zero.
// Note that the comparison against zero operation is not available if we
// have vector support, since load-and-test instructions will partially
// clobber the target (vector) register.
multiclass LoadAndTestRRE<string mnemonic, bits<16> opcode,
RegisterOperand cls> {
def "" : UnaryRRE<mnemonic, opcode, null_frag, cls, cls>;
let isCodeGenOnly = 1, Predicates = [FeatureNoVector] in
def Compare : CompareRRE<mnemonic, opcode, null_frag, cls, cls>;
}

//===----------------------------------------------------------------------===//
// Pseudo instructions
//===----------------------------------------------------------------------===//
Expand Down
3 changes: 0 additions & 3 deletions llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1692,9 +1692,6 @@ unsigned SystemZInstrInfo::getLoadAndTest(unsigned Opcode) const {
case SystemZ::LR: return SystemZ::LTR;
case SystemZ::LGFR: return SystemZ::LTGFR;
case SystemZ::LGR: return SystemZ::LTGR;
case SystemZ::LER: return SystemZ::LTEBR;
case SystemZ::LDR: return SystemZ::LTDBR;
case SystemZ::LXR: return SystemZ::LTXBR;
case SystemZ::LCDFR: return SystemZ::LCDBR;
case SystemZ::LPDFR: return SystemZ::LPDBR;
case SystemZ::LNDFR: return SystemZ::LNDBR;
Expand Down
7 changes: 3 additions & 4 deletions llvm/lib/Target/SystemZ/SystemZPatterns.td
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,11 @@ multiclass BlockLoadStore<SDPatternOperator load, ValueType vt,
}

// Record that INSN is a LOAD AND TEST that can be used to compare
// registers in CLS against zero. The instruction has separate R1 and R2
// operands, but they must be the same when the instruction is used like this.
// registers in CLS against zero.
multiclass CompareZeroFP<Instruction insn, RegisterOperand cls> {
def : Pat<(z_any_fcmp cls:$reg, (fpimm0)), (insn cls:$reg, cls:$reg)>;
def : Pat<(z_any_fcmp cls:$reg, (fpimm0)), (insn cls:$reg)>;
// The sign of the zero makes no difference.
def : Pat<(z_any_fcmp cls:$reg, (fpimmneg0)), (insn cls:$reg, cls:$reg)>;
def : Pat<(z_any_fcmp cls:$reg, (fpimmneg0)), (insn cls:$reg)>;
}

// Use INSN for performing binary operation OPERATION of type VT
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/Target/SystemZ/SystemZScheduleZ13.td
Original file line number Diff line number Diff line change
Expand Up @@ -784,9 +784,7 @@ def : InstRW<[WLat2, FXb2, GroupAlone], (instregex "LXR$")>;

// Load and Test
def : InstRW<[WLat3, WLat3, VecXsPm, NormalGr], (instregex "LT(E|D)BR$")>;
def : InstRW<[WLat3, VecXsPm, NormalGr], (instregex "LT(E|D)BRCompare$")>;
def : InstRW<[WLat10, WLat10, VecDF4, GroupAlone],
(instregex "LTXBR(Compare)?$")>;
def : InstRW<[WLat10, WLat10, VecDF4, GroupAlone], (instregex "LTXBR$")>;

// Copy sign
def : InstRW<[WLat2, VecXsPm, NormalGr], (instregex "CPSDR(d|s)(d|s)$")>;
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/Target/SystemZ/SystemZScheduleZ14.td
Original file line number Diff line number Diff line change
Expand Up @@ -804,9 +804,7 @@ def : InstRW<[WLat2, FXb2, GroupAlone], (instregex "LXR$")>;

// Load and Test
def : InstRW<[WLat3, WLat3, VecXsPm, NormalGr], (instregex "LT(E|D)BR$")>;
def : InstRW<[WLat3, VecXsPm, NormalGr], (instregex "LT(E|D)BRCompare$")>;
def : InstRW<[WLat10, WLat10, VecDF4, GroupAlone],
(instregex "LTXBR(Compare)?$")>;
def : InstRW<[WLat10, WLat10, VecDF4, GroupAlone], (instregex "LTXBR$")>;

// Copy sign
def : InstRW<[WLat2, VecXsPm, NormalGr], (instregex "CPSDR(d|s)(d|s)$")>;
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/Target/SystemZ/SystemZScheduleZ15.td
Original file line number Diff line number Diff line change
Expand Up @@ -821,9 +821,7 @@ def : InstRW<[WLat2, FXb2, GroupAlone], (instregex "LXR$")>;

// Load and Test
def : InstRW<[WLat3, WLat3, VecXsPm, NormalGr], (instregex "LT(E|D)BR$")>;
def : InstRW<[WLat3, VecXsPm, NormalGr], (instregex "LT(E|D)BRCompare$")>;
def : InstRW<[WLat10, WLat10, VecDF4, GroupAlone],
(instregex "LTXBR(Compare)?$")>;
def : InstRW<[WLat10, WLat10, VecDF4, GroupAlone], (instregex "LTXBR$")>;

// Copy sign
def : InstRW<[WLat2, VecXsPm, NormalGr], (instregex "CPSDR(d|s)(d|s)$")>;
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/Target/SystemZ/SystemZScheduleZ16.td
Original file line number Diff line number Diff line change
Expand Up @@ -822,9 +822,7 @@ def : InstRW<[WLat2, FXb2, GroupAlone], (instregex "LXR$")>;

// Load and Test
def : InstRW<[WLat3, WLat3, VecXsPm, NormalGr], (instregex "LT(E|D)BR$")>;
def : InstRW<[WLat3, VecXsPm, NormalGr], (instregex "LT(E|D)BRCompare$")>;
def : InstRW<[WLat10, WLat10, VecDF4, GroupAlone],
(instregex "LTXBR(Compare)?$")>;
def : InstRW<[WLat10, WLat10, VecDF4, GroupAlone], (instregex "LTXBR$")>;

// Copy sign
def : InstRW<[WLat2, VecXsPm, NormalGr], (instregex "CPSDR(d|s)(d|s)$")>;
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/SystemZ/SystemZScheduleZ196.td
Original file line number Diff line number Diff line change
Expand Up @@ -716,8 +716,7 @@ def : InstRW<[WLat2, FXU2, GroupAlone2], (instregex "LXR$")>;

// Load and Test
def : InstRW<[WLat9, WLat9, FPU, NormalGr], (instregex "LT(E|D)BR$")>;
def : InstRW<[WLat9, FPU, NormalGr], (instregex "LT(E|D)BRCompare$")>;
def : InstRW<[WLat10, WLat10, FPU4, GroupAlone], (instregex "LTXBR(Compare)?$")>;
def : InstRW<[WLat10, WLat10, FPU4, GroupAlone], (instregex "LTXBR$")>;

// Copy sign
def : InstRW<[WLat5, FXU2, GroupAlone], (instregex "CPSDR(d|s)(d|s)$")>;
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td
Original file line number Diff line number Diff line change
Expand Up @@ -754,8 +754,7 @@ def : InstRW<[WLat2, FXU2, GroupAlone], (instregex "LXR$")>;

// Load and Test
def : InstRW<[WLat9, WLat9, FPU, NormalGr], (instregex "LT(E|D)BR$")>;
def : InstRW<[WLat9, FPU, NormalGr], (instregex "LT(E|D)BRCompare$")>;
def : InstRW<[WLat10, WLat10, FPU4, GroupAlone], (instregex "LTXBR(Compare)?$")>;
def : InstRW<[WLat10, WLat10, FPU4, GroupAlone], (instregex "LTXBR$")>;

// Copy sign
def : InstRW<[WLat5, FXU2, GroupAlone], (instregex "CPSDR(d|s)(d|s)$")>;
Expand Down
31 changes: 16 additions & 15 deletions llvm/test/CodeGen/SystemZ/fp-cmp-04.ll
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ exit:
define float @f9(float %a, float %b, ptr %dest) {
; CHECK-LABEL: f9:
; CHECK: meebr %f0, %f2
; CHECK-NEXT: ltebr %f0, %f0
; CHECK-NEXT: ltebr %f1, %f0
; CHECK-NEXT: blhr %r14
; CHECK: br %r14
entry:
Expand All @@ -185,7 +185,7 @@ define float @f10(float %a, float %b, float %c, ptr %dest) {
; CHECK-LABEL: f10:
; CHECK: aebr %f0, %f2
; CHECK-NEXT: debr %f0, %f4
; CHECK-NEXT: ltebr %f0, %f0
; CHECK-NEXT: ltebr %f1, %f0
; CHECK-NEXT: bner %r14
; CHECK: br %r14
entry:
Expand All @@ -209,7 +209,7 @@ define float @f11(float %a, float %b, float %c, ptr %dest1, ptr %dest2) {
; CHECK: aebr %f0, %f2
; CHECK-NEXT: sebr %f4, %f0
; CHECK-DAG: ste %f4, 0(%r2)
; CHECK-DAG: ltebr %f0, %f0
; CHECK-DAG: ltebr %f1, %f0
; CHECK-NEXT: ber %r14
; CHECK: br %r14
entry:
Expand All @@ -227,10 +227,11 @@ exit:
ret float %add
}

; Test that LER gets converted to LTEBR where useful.
; %val in %f2 must be preserved during comparison and also copied to %f0.
define float @f12(float %dummy, float %val, ptr %dest) {
; CHECK-LABEL: f12:
; CHECK: ltebr %f0, %f2
; CHECK: ler %f0, %f2
; CHECK-NEXT: ltebr %f1, %f2
; CHECK-NEXT: #APP
; CHECK-NEXT: blah %f0
; CHECK-NEXT: #NO_APP
Expand All @@ -249,10 +250,11 @@ exit:
ret float %val
}

; Test that LDR gets converted to LTDBR where useful.
; Same for double.
define double @f13(double %dummy, double %val, ptr %dest) {
; CHECK-LABEL: f13:
; CHECK: ltdbr %f0, %f2
; CHECK: ldr %f0, %f2
; CHECK-NEXT: ltdbr %f1, %f2
; CHECK-NEXT: #APP
; CHECK-NEXT: blah %f0
; CHECK-NEXT: #NO_APP
Expand All @@ -271,14 +273,15 @@ exit:
ret double %val
}

; Test that LXR gets converted to LTXBR where useful.
; LXR cannot be converted to LTXBR as its input is live after it.
define void @f14(ptr %ptr1, ptr %ptr2) {
; CHECK-LABEL: f14:
; CHECK: ltxbr
; CHECK: lxr
; CHECK-NEXT: dxbr
; CHECK-NEXT: std
; CHECK-NEXT: std
; CHECK-NEXT: mxbr
; CHECK-NEXT: ltxbr
; CHECK-NEXT: std
; CHECK-NEXT: std
; CHECK-NEXT: blr %r14
Expand All @@ -301,11 +304,10 @@ exit:
ret void
}

; Test a case where it is the source rather than destination of LER that
; we need.
define float @f15(float %val, float %dummy, ptr %dest) {
; CHECK-LABEL: f15:
; CHECK: ltebr %f2, %f0
; CHECK: ltebr %f1, %f0
; CHECK-NEXT: ler %f2, %f0
; CHECK-NEXT: #APP
; CHECK-NEXT: blah %f2
; CHECK-NEXT: #NO_APP
Expand All @@ -324,11 +326,10 @@ exit:
ret float %val
}

; Test a case where it is the source rather than destination of LDR that
; we need.
define double @f16(double %val, double %dummy, ptr %dest) {
; CHECK-LABEL: f16:
; CHECK: ltdbr %f2, %f0
; CHECK: ltdbr %f1, %f0
; CHECK: ldr %f2, %f0
; CHECK-NEXT: #APP
; CHECK-NEXT: blah %f2
; CHECK-NEXT: #NO_APP
Expand Down
44 changes: 0 additions & 44 deletions llvm/test/CodeGen/SystemZ/fp-cmp-07.mir

This file was deleted.

Loading