[llvm] FastISel: Assert the emitted instruction defines the result (PR #226502)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 07:04:11 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/226502
The fallback path copied the result out of implicit_defs()[0], assuming
the first implicit physical register def is the result. That is an X86
assumption about MUL/IMUL, and it is unreachable for all but
fastEmitInst_r: FastISelEmitter skips any instruction whose first
operand is not an output register, so every opcode reaching these
helpers from generated code has an explicit def.
Co-Authored-By: Claude Opus 5 <noreply at anthropic.com>
>From ef991e5b84ba579d4a8afdc87d8e48e87e4b83b6 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 25 Sep 2026 16:01:33 +0200
Subject: [PATCH] FastISel: Assert the emitted instruction defines the result
The fallback path copied the result out of implicit_defs()[0], assuming
the first implicit physical register def is the result. That is an X86
assumption about MUL/IMUL, and it is unreachable for all but
fastEmitInst_r: FastISelEmitter skips any instruction whose first
operand is not an output register, so every opcode reaching these
helpers from generated code has an explicit def.
Co-Authored-By: Claude Opus 5 <noreply at anthropic.com>
---
llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 113 +++++----------------
1 file changed, 28 insertions(+), 85 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 5fc4611d077b0..5cbc7f385304d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -2018,18 +2018,10 @@ Register FastISel::fastEmitInst_rr(unsigned MachineInstOpcode,
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);
- if (II.getNumDefs() >= 1)
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
- .addReg(Op0)
- .addReg(Op1);
- else {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
- .addReg(Op0)
- .addReg(Op1);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
- ResultReg)
- .addReg(II.implicit_defs()[0]);
- }
+ assert(II.getNumDefs() >= 1 && "instruction must define the result");
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
+ .addReg(Op0)
+ .addReg(Op1);
return ResultReg;
}
@@ -2043,20 +2035,11 @@ Register FastISel::fastEmitInst_rrr(unsigned MachineInstOpcode,
Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);
Op2 = constrainOperandRegClass(II, Op2, II.getNumDefs() + 2);
- if (II.getNumDefs() >= 1)
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
- .addReg(Op0)
- .addReg(Op1)
- .addReg(Op2);
- else {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
- .addReg(Op0)
- .addReg(Op1)
- .addReg(Op2);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
- ResultReg)
- .addReg(II.implicit_defs()[0]);
- }
+ assert(II.getNumDefs() >= 1 && "instruction must define the result");
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
+ .addReg(Op0)
+ .addReg(Op1)
+ .addReg(Op2);
return ResultReg;
}
@@ -2068,18 +2051,10 @@ Register FastISel::fastEmitInst_ri(unsigned MachineInstOpcode,
Register ResultReg = createResultReg(RC);
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
- if (II.getNumDefs() >= 1)
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
- .addReg(Op0)
- .addImm(Imm);
- else {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
- .addReg(Op0)
- .addImm(Imm);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
- ResultReg)
- .addReg(II.implicit_defs()[0]);
- }
+ assert(II.getNumDefs() >= 1 && "instruction must define the result");
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
+ .addReg(Op0)
+ .addImm(Imm);
return ResultReg;
}
@@ -2091,20 +2066,11 @@ Register FastISel::fastEmitInst_rii(unsigned MachineInstOpcode,
Register ResultReg = createResultReg(RC);
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
- if (II.getNumDefs() >= 1)
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
- .addReg(Op0)
- .addImm(Imm1)
- .addImm(Imm2);
- else {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
- .addReg(Op0)
- .addImm(Imm1)
- .addImm(Imm2);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
- ResultReg)
- .addReg(II.implicit_defs()[0]);
- }
+ assert(II.getNumDefs() >= 1 && "instruction must define the result");
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
+ .addReg(Op0)
+ .addImm(Imm1)
+ .addImm(Imm2);
return ResultReg;
}
@@ -2115,16 +2081,9 @@ Register FastISel::fastEmitInst_f(unsigned MachineInstOpcode,
Register ResultReg = createResultReg(RC);
- if (II.getNumDefs() >= 1)
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
- .addFPImm(FPImm);
- else {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
- .addFPImm(FPImm);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
- ResultReg)
- .addReg(II.implicit_defs()[0]);
- }
+ assert(II.getNumDefs() >= 1 && "instruction must define the result");
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
+ .addFPImm(FPImm);
return ResultReg;
}
@@ -2137,20 +2096,11 @@ Register FastISel::fastEmitInst_rri(unsigned MachineInstOpcode,
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);
- if (II.getNumDefs() >= 1)
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
- .addReg(Op0)
- .addReg(Op1)
- .addImm(Imm);
- else {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
- .addReg(Op0)
- .addReg(Op1)
- .addImm(Imm);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
- ResultReg)
- .addReg(II.implicit_defs()[0]);
- }
+ assert(II.getNumDefs() >= 1 && "instruction must define the result");
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
+ .addReg(Op0)
+ .addReg(Op1)
+ .addImm(Imm);
return ResultReg;
}
@@ -2159,15 +2109,8 @@ Register FastISel::fastEmitInst_i(unsigned MachineInstOpcode,
Register ResultReg = createResultReg(RC);
const MCInstrDesc &II = TII.get(MachineInstOpcode);
- if (II.getNumDefs() >= 1)
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
- .addImm(Imm);
- else {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II).addImm(Imm);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
- ResultReg)
- .addReg(II.implicit_defs()[0]);
- }
+ assert(II.getNumDefs() >= 1 && "instruction must define the result");
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg).addImm(Imm);
return ResultReg;
}
More information about the llvm-commits
mailing list