Skip to content

Commit 225b6df

Browse files
jfuenteshliao2
authored andcommitted
Remove ASSIGN_TYPE for iadd reg imm generation
This PR complements #4 for generating iadd with immediate source operand. Immediates from LLVM IR are mapped to G_CONSTANT in GMIR, and in the SPIRV implementation, ASSIGN_TYPE is used to assign the register type to instruction destination. For example, the following code sequence represents a constant with type assignment: ``` %1:type(s32) = OpTypeInt 16, 0 %11:_(s32) = G_CONSTANT i32 5 %5:anyreg(s32) = ASSIGN_TYPE %11:_(s32), %1:type(s32) ``` With this PR, ASSIGN_TYPE is removed and the type of the G_CONSTANT destination is set directly from src operand ``i32 5``. New code sequence is: ``` $11:reg32b(s32) = G_CONSTANT i32 5 ```
1 parent bf30023 commit 225b6df

File tree

3 files changed

+64
-111
lines changed

3 files changed

+64
-111
lines changed

llvm/lib/Target/pISA/pISAPreLegalizer.cpp

Lines changed: 19 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -222,83 +222,6 @@ Register insertAssignInstr(Register Reg, Type *Ty, pISAType *pISATy,
222222
}
223223
} // namespace llvm
224224

225-
static void generateAssignInstrs(MachineFunction &MF, pISAGlobalRegistry *GR,
226-
MachineIRBuilder MIB) {
227-
MachineRegisterInfo &MRI = MF.getRegInfo();
228-
SmallVector<MachineInstr *, 10> ToErase;
229-
230-
for (MachineBasicBlock *MBB : post_order(&MF)) {
231-
if (MBB->empty())
232-
continue;
233-
234-
bool ReachedBegin = false;
235-
for (auto MII = std::prev(MBB->end()), Begin = MBB->begin();
236-
!ReachedBegin;) {
237-
MachineInstr &MI = *MII;
238-
239-
if (ispISAIntrinsic(MI, Intrinsic::pisa_assign_type)) {
240-
Register Reg = MI.getOperand(1).getReg();
241-
Type *Ty = getMDOperandAsType(MI.getOperand(2).getMetadata(), 0);
242-
MachineInstr *Def = MRI.getVRegDef(Reg);
243-
assert(Def && "Expecting an instruction that defines the register");
244-
// G_GLOBAL_VALUE already has type info.
245-
if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE)
246-
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MF.getRegInfo());
247-
ToErase.push_back(&MI);
248-
} else if (MI.getOpcode() == TargetOpcode::G_CONSTANT ||
249-
MI.getOpcode() == TargetOpcode::G_FCONSTANT ||
250-
MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
251-
// %rc = G_CONSTANT ty Val
252-
// ===>
253-
// %cty = OpType* ty
254-
// %rctmp = G_CONSTANT ty Val
255-
// %rc = ASSIGN_TYPE %rctmp, %cty
256-
Register Reg = MI.getOperand(0).getReg();
257-
if (MRI.hasOneUse(Reg)) {
258-
MachineInstr &UseMI = *MRI.use_instr_begin(Reg);
259-
if (ispISAIntrinsic(UseMI, Intrinsic::pisa_assign_type) ||
260-
ispISAIntrinsic(UseMI, Intrinsic::pisa_assign_name))
261-
continue;
262-
}
263-
Type *Ty = nullptr;
264-
if (MI.getOpcode() == TargetOpcode::G_CONSTANT)
265-
Ty = MI.getOperand(1).getCImm()->getType();
266-
else if (MI.getOpcode() == TargetOpcode::G_FCONSTANT)
267-
Ty = MI.getOperand(1).getFPImm()->getType();
268-
else {
269-
assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
270-
Type *ElemTy = nullptr;
271-
MachineInstr *ElemMI = MRI.getVRegDef(MI.getOperand(1).getReg());
272-
assert(ElemMI);
273-
274-
if (ElemMI->getOpcode() == TargetOpcode::G_CONSTANT)
275-
ElemTy = ElemMI->getOperand(1).getCImm()->getType();
276-
else if (ElemMI->getOpcode() == TargetOpcode::G_FCONSTANT)
277-
ElemTy = ElemMI->getOperand(1).getFPImm()->getType();
278-
else
279-
llvm_unreachable("Unexpected opcode");
280-
unsigned NumElts =
281-
MI.getNumExplicitOperands() - MI.getNumExplicitDefs();
282-
Ty = VectorType::get(ElemTy, NumElts, false);
283-
}
284-
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
285-
} else if (MI.getOpcode() == TargetOpcode::G_TRUNC ||
286-
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
287-
MI.getOpcode() == TargetOpcode::COPY ||
288-
MI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST) {
289-
propagatepISAType(&MI, GR, MRI, MIB);
290-
}
291-
292-
if (MII == Begin)
293-
ReachedBegin = true;
294-
else
295-
--MII;
296-
}
297-
}
298-
for (MachineInstr *MI : ToErase)
299-
MI->eraseFromParent();
300-
}
301-
302225
static std::pair<Register, unsigned>
303226
createNewIdReg(Register ValReg, unsigned Opcode, MachineRegisterInfo &MRI,
304227
const pISAGlobalRegistry &GR) {
@@ -328,18 +251,28 @@ createNewIdReg(Register ValReg, unsigned Opcode, MachineRegisterInfo &MRI,
328251
}
329252

330253
static std::pair<Register, unsigned>
331-
updateDstRegFromOperand(Register DstReg, Register ValReg, unsigned Opcode,
254+
updateDstRegFromOperand(MachineOperand &Dst, MachineOperand &Src, unsigned Opcode,
332255
MachineRegisterInfo &MRI, const pISAGlobalRegistry &GR) {
333-
pISAType *pISAType = GR.getpISATypeForVReg(ValReg);
334-
assert(pISAType && "VReg is expected to have pISA type");
335-
auto bitSize = MRI.getType(ValReg).getSizeInBits();
256+
unsigned BitSize = 32;
257+
if (Src.isReg()) {
258+
// Src operand is a virtual register of known bit-width
259+
auto SrcReg = Src.getReg();
260+
auto pISAType = GR.getpISATypeForVReg(SrcReg);
261+
assert(pISAType && "Src is expected to have pISA type");
262+
BitSize = MRI.getType(SrcReg).getSizeInBits();
263+
} else if (Src.isCImm()) {
264+
// Src operand is a constant immediate
265+
BitSize = Src.getCImm()->getBitWidth();
266+
} else {
267+
llvm_unreachable("Src operand can only be a virtual register or immediate");
268+
}
336269

337270
LLT NewT = LLT::scalar(32);
338271
auto GetIdOp = pISA::GET_Reg32b;
339272
auto DstClass = &pISA::Reg32bRegClass;
340273

341274
// TODO: Handle other bitwidths if needed
342-
switch (bitSize) {
275+
switch (BitSize) {
343276
case 16:
344277
NewT = LLT::scalar(16);
345278
GetIdOp = pISA::GET_Reg16b;
@@ -354,9 +287,10 @@ updateDstRegFromOperand(Register DstReg, Register ValReg, unsigned Opcode,
354287
DstClass = &pISA::Reg64bRegClass;
355288
break;
356289
default:
357-
assert(false && "Bit size not supported for new reg var");
290+
llvm_unreachable("Bit size not supported for new reg var");
358291
}
359292

293+
auto DstReg = Dst.getReg();
360294
MRI.setRegClass(DstReg, DstClass);
361295
MRI.setType(DstReg, NewT);
362296
MRI.noteNewVirtualRegister(DstReg);
@@ -374,8 +308,8 @@ static void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
374308
// all instructions operands at once.
375309
unsigned Opc = MI.getOpcode();
376310
auto NewReg =
377-
updateDstRegFromOperand(MI.getOperand(0).getReg(),
378-
MI.getOperand(1).getReg(), Opc, MRI, *GR)
311+
updateDstRegFromOperand(MI.getOperand(0),
312+
MI.getOperand(1), Opc, MRI, *GR)
379313
.first;
380314

381315
MI.getOperand(0).setReg(NewReg);
@@ -397,30 +331,6 @@ static void processInstrsWithTypeFolding(MachineFunction &MF,
397331
processInstr(MI, MIB, MRI, GR);
398332
}
399333
}
400-
for (MachineBasicBlock &MBB : MF) {
401-
for (MachineInstr &MI : MBB) {
402-
// We need to rewrite dst types for ASSIGN_TYPE instrs to be able
403-
// to perform tblgen'erated selection and we can't do that on Legalizer
404-
// as it operates on gMIR only.
405-
if (MI.getOpcode() != pISA::ASSIGN_TYPE)
406-
continue;
407-
Register SrcReg = MI.getOperand(1).getReg();
408-
unsigned Opcode = MRI.getVRegDef(SrcReg)->getOpcode();
409-
if (!isTypeFoldingSupported(Opcode))
410-
continue;
411-
Register DstReg = MI.getOperand(0).getReg();
412-
if (MRI.getType(DstReg).isVector())
413-
MRI.setRegClass(DstReg, &pISA::Reg32bRegClass);
414-
// Don't need to reset type of register holding constant and used in
415-
// G_ADDRSPACE_CAST, since it braaks legalizer.
416-
if (Opcode == TargetOpcode::G_CONSTANT && MRI.hasOneUse(DstReg)) {
417-
MachineInstr &UseMI = *MRI.use_instr_begin(DstReg);
418-
if (UseMI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST)
419-
continue;
420-
}
421-
MRI.setType(DstReg, LLT::scalar(32));
422-
}
423-
}
424334
}
425335

426336
static void processSwitches(MachineFunction &MF, pISAGlobalRegistry *GR,
@@ -587,7 +497,6 @@ bool pISAPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
587497
addConstantsToTrack(MF, GR);
588498
foldConstantsIntoIntrinsics(MF);
589499
insertBitcasts(MF, GR, MIB);
590-
generateAssignInstrs(MF, GR, MIB);
591500
processSwitches(MF, GR, MIB);
592501
processInstrsWithTypeFolding(MF, GR, MIB);
593502

llvm/test/CodeGen/MIR/pISA/iadd.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
; RUN: llc -march=pisa64 -stop-after=finalize-isel -o %t.mir %s
2+
; RUN: llc -march=pisa64 -run-pass=none %t.mir -o - | FileCheck %s
3+
4+
; This MIR test if for checking instruction selection for iadd after
5+
; finalize-isel pass.
6+
7+
; CHECK-LABEL: {{^}}name: test_iadd32
8+
define i32 @test_iadd32(i32 %a, i32 %b) {
9+
; CHECK: %{{[0-9]+}}:reg32b = iadd32rr %{{[0-9]+}}, %{{[0-9]+}}
10+
%result = add i32 %a, %b
11+
ret i32 %result
12+
}
13+
14+
; CHECK-LABEL: {{^}}name: test_iadd32imm
15+
define i32 @test_iadd32imm(i32 %a) {
16+
; CHECK: %{{[0-9]+}}:reg32b = iadd32ri %{{[0-9]+}}, 5
17+
%result = add i32 %a, 5
18+
ret i32 %result
19+
}

llvm/test/CodeGen/pISA/iadd-fadd.ll renamed to llvm/test/CodeGen/pISA/iadd.ll

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,29 @@ define i16 @test_iadd16(i16 %a, i16 %b) {
2222
; ADD-NEXT: return [[RES]]
2323
%result = add i16 %a, %b
2424
ret i16 %result
25-
}
25+
}
26+
27+
; CHECK-LABEL: @test_iadd64imm
28+
define i64 @test_iadd64imm(i64 %a) {
29+
; ADD: iadd.64b [[RES:%r[0-9]+]], %r{{[0-9]+}}, 5
30+
; ADD-NEXT: return [[RES]]
31+
%result = add i64 %a, 5
32+
ret i64 %result
33+
}
34+
35+
; CHECK-LABEL: @test_iadd32imm
36+
define i32 @test_iadd32imm(i32 %a) {
37+
; ADD: iadd.32b [[RES:%r[0-9]+]], %r{{[0-9]+}}, 5
38+
; ADD-NEXT: return [[RES]]
39+
%result = add i32 %a, 5
40+
ret i32 %result
41+
}
42+
43+
; CHECK-LABEL: @test_iadd16imm
44+
define i16 @test_iadd16imm(i16 %a) {
45+
; ADD: iadd.16b [[RES:%r[0-9]+]], %r{{[0-9]+}}, 5
46+
; ADD-NEXT: return [[RES]]
47+
%result = add i16 %a, 5
48+
ret i16 %result
49+
}
50+

0 commit comments

Comments
 (0)