Skip to content

Commit c359618

Browse files
committed
[EraVM] Do not set Uses=[Flags] unconditionally in JCl
1 parent 628e115 commit c359618

File tree

7 files changed

+58
-14
lines changed

7 files changed

+58
-14
lines changed

llvm/lib/Target/EraVM/EraVMAsmPrinter.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,17 @@ void EraVMAsmPrinter::emitInstruction(const MachineInstr *MI) {
150150
llvm_unreachable("pseudo opcode found in emitInstruction()");
151151
}
152152

153+
// All non-pseudo instructions can be predicated.
154+
const auto *CCOperand = EraVM::ccIterator(*MI);
155+
unsigned CondCode = getImmOrCImm(*CCOperand);
156+
assert(CondCode != (unsigned)EraVMCC::COND_INVALID);
157+
if (CondCode && !MI->hasRegisterImplicitUseOperand(EraVM::Flags)) {
158+
#ifndef NDEBUG
159+
MI->dump();
160+
#endif
161+
llvm_unreachable("Predicated instruction should use Flags register");
162+
}
163+
153164
MCInstLowering.Lower(MI, TmpInst);
154165
EmitToStreamer(*OutStreamer, TmpInst);
155166
}

llvm/lib/Target/EraVM/EraVMISelLowering.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,11 +1411,6 @@ void EraVMTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
14111411
SDNode *Node) const {
14121412
assert(MI.hasPostISelHook() && "Expected instruction to have post-isel hook");
14131413

1414-
// Set NoMerge to gasleft instructions. This has to be in sync with nomerge
1415-
// attribute in IntrinsicsEraVM.td for this intrinsic.
1416-
if (MI.getOpcode() == EraVM::CTXGasLeft)
1417-
MI.setFlag(MachineInstr::MIFlag::NoMerge);
1418-
14191414
// The overflow LT aka COND_OF caused by uaddo and umulo hasn't reversal
14201415
// version actually, the GE can't be used according to the spec. We need to
14211416
// add early-clobber attribute to the output register to prevent the RegAlloc
@@ -1425,12 +1420,35 @@ void EraVMTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
14251420
// out = SELrrr i1 %ov, in0, in1, COND_OF
14261421
//
14271422
// when out and in0 are assigned to same register.
1428-
if (EraVM::isSelect(MI) &&
1429-
getImmOrCImm(*EraVM::ccIterator(MI)) == EraVMCC::COND_OF) {
1423+
if (EraVM::isSelect(MI)) {
1424+
if (getImmOrCImm(*EraVM::ccIterator(MI)) != EraVMCC::COND_OF)
1425+
return;
14301426
assert(
14311427
(EraVM::argumentType(EraVM::ArgumentKind::In0, MI.getOpcode()) ==
14321428
EraVM::ArgumentType::Register) &&
14331429
"Expect register operand for the 1st input of SELECT with overflow LT");
14341430
EraVM::out0Iterator(MI)->setIsEarlyClobber();
1431+
return;
1432+
}
1433+
1434+
switch (MI.getOpcode()) {
1435+
default:
1436+
llvm_unreachable("Unexpected instruction passed to post-isel hook");
1437+
case EraVM::JCl: {
1438+
const auto *CCOperand = EraVM::ccIterator(MI);
1439+
if (getImmOrCImm(*CCOperand) == EraVMCC::COND_NONE) {
1440+
// Instruction is not predicated - drop implicit use of Flags register.
1441+
int FlagsUseIdx = MI.findRegisterUseOperandIdx(EraVM::Flags);
1442+
assert(FlagsUseIdx < 0 && "Conservative Uses=[Flags] expected");
1443+
assert(MI.getOperand(FlagsUseIdx).isImplicit());
1444+
MI.removeOperand(FlagsUseIdx);
1445+
}
1446+
break;
1447+
}
1448+
case EraVM::CTXGasLeft:
1449+
// Set NoMerge to gasleft instructions. This has to be in sync with nomerge
1450+
// attribute in IntrinsicsEraVM.td for this intrinsic.
1451+
MI.setFlag(MachineInstr::MIFlag::NoMerge);
1452+
break;
14351453
}
14361454
}

llvm/lib/Target/EraVM/EraVMInstrFormats.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,19 @@ class IForm <EraVMOpcode opcode,
310310
let UseLogicalOperandMappings = true;
311311
}
312312

313+
// Mix-in class for IForm instances that can be predicated by the
314+
// tablegen-erated instruction selector rules.
315+
// Note: if marking an instruction with this mix-in, add one more `case` line
316+
// to EraVMTargetLowering::AdjustInstrPostInstrSelection.
317+
class MayBePredicatedViaPattern {
318+
// Make ISel conservatively assume Flags register is used by this instruction
319+
// and drop this Use in AdjustInstrPostInstrSelection as needed.
320+
// This prevents incorrecly marking previous Defs as dead if the instruction
321+
// is actually predicated.
322+
list<Register> Uses = [Flags];
323+
bit hasPostISelHook = true;
324+
}
325+
313326
class IJump<EraVMOpcode opcode,
314327
SrcMode src,
315328
dag outs, dag ins, string asmstr, list<dag> pattern>

llvm/lib/Target/EraVM/EraVMInstrInfo.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,12 @@ unsigned EraVMInstrInfo::insertBranch(
405405
}
406406
// Conditional branch.
407407
unsigned Count = 0;
408-
auto cond_code = getImmOrCImm(Cond[0]);
409-
BuildMI(&MBB, DL, get(EraVM::JCl)).addMBB(TBB).addImm(cond_code);
408+
auto CondCode = getImmOrCImm(Cond[0]);
409+
const MachineInstrBuilder &MIB =
410+
BuildMI(&MBB, DL, get(EraVM::JCl)).addMBB(TBB).addImm(CondCode);
411+
// Do not accidentally use a dead register.
412+
if (CondCode != EraVMCC::COND_NONE)
413+
MIB.addUse(EraVM::Flags, RegState::Implicit);
410414
++Count;
411415

412416
if (FBB) {

llvm/lib/Target/EraVM/EraVMInstrInfo.td

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -971,10 +971,9 @@ class JumpViaStack : JumpViaConst;
971971
// a return address operand can be used as a cheaper replacement for "call",
972972
// so it may be worth making it non-terminator in the future.
973973

974-
let Uses = [Flags] in // TODO Do not set implicit use unconditionally.
975974
def JCl : IJump<OpJump, SrcImm, (outs), (ins jmptarget:$dest), "$dest",
976975
[(EraVMbrcc bb:$dest, imm:$cc)]>,
977-
JumpWithoutRetAddr, JumpViaLabel;
976+
JumpWithoutRetAddr, JumpViaLabel, MayBePredicatedViaPattern;
978977
def JClr : IJump<OpJump, SrcImm, (outs GR256:$ret_addr), (ins jmptarget:$dest), "$dest, $ret_addr", []>,
979978
JumpWithRetAddr, JumpViaLabel;
980979

llvm/lib/Target/EraVM/EraVMOptimizeSelectPostRA.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,7 @@ bool EraVMOptimizeSelectPostRA::runOnMachineFunction(MachineFunction &MF) {
232232
for (auto [CMov, FoldInst] : Deleted) {
233233
LLVM_DEBUG(dbgs() << "== Folding cond move:"; CMov->dump();
234234
dbgs() << " into:"; FoldInst->dump(););
235-
EraVM::ccIterator(*FoldInst)->ChangeToImmediate(
236-
getImmOrCImm(*EraVM::ccIterator(*CMov)));
235+
TII->PredicateInstruction(*FoldInst, ArrayRef(*EraVM::ccIterator(*CMov)));
237236
EraVM::out0Iterator(*FoldInst)->setReg(
238237
EraVM::out0Iterator(*CMov)->getReg());
239238
CMov->eraseFromParent();

llvm/test/CodeGen/EraVM/select_fold.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
---
4747
# CHECK-LABEL: test_add_reg
4848
# CHECK-LABEL: bb.0:
49-
# CHECK: $r1 = ADDrrr_s $r1, $r1, 9
49+
# CHECK: $r1 = ADDrrr_s $r1, $r1, i256 9, implicit $flags
5050
name: test_add_reg
5151
tracksRegLiveness: true
5252
body: |

0 commit comments

Comments
 (0)