Skip to content

Commit

Permalink
GlobalISel: Avoid use of G_INSERT in insertParts
Browse files Browse the repository at this point in the history
G_INSERT legalization is incomplete and doesn't work very
well. Instead try to use sequences of G_MERGE_VALUES/G_UNMERGE_VALUES
padding with undef values (although this can get pretty large).

For the case of load/store narrowing, this is still performing the
load/stores in irregularly sized pieces. It might be cleaner to split
this down into equal sized pieces, and rely on load/store merging to
optimize it.
  • Loading branch information
arsenm committed Jun 8, 2021
1 parent 2927d40 commit 31a9659
Show file tree
Hide file tree
Showing 23 changed files with 5,900 additions and 4,720 deletions.
29 changes: 8 additions & 21 deletions llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
Expand Up @@ -220,29 +220,16 @@ void LegalizerHelper::insertParts(Register DstReg,
return;
}

unsigned PartSize = PartTy.getSizeInBits();
unsigned LeftoverPartSize = LeftoverTy.getSizeInBits();
SmallVector<Register> GCDRegs;
LLT GCDTy;
for (Register PartReg : PartRegs)
GCDTy = extractGCDType(GCDRegs, ResultTy, LeftoverTy, PartReg);

Register CurResultReg = MRI.createGenericVirtualRegister(ResultTy);
MIRBuilder.buildUndef(CurResultReg);
for (Register PartReg : LeftoverRegs)
extractGCDType(GCDRegs, ResultTy, LeftoverTy, PartReg);

unsigned Offset = 0;
for (Register PartReg : PartRegs) {
Register NewResultReg = MRI.createGenericVirtualRegister(ResultTy);
MIRBuilder.buildInsert(NewResultReg, CurResultReg, PartReg, Offset);
CurResultReg = NewResultReg;
Offset += PartSize;
}

for (unsigned I = 0, E = LeftoverRegs.size(); I != E; ++I) {
// Use the original output register for the final insert to avoid a copy.
Register NewResultReg = (I + 1 == E) ?
DstReg : MRI.createGenericVirtualRegister(ResultTy);

MIRBuilder.buildInsert(NewResultReg, CurResultReg, LeftoverRegs[I], Offset);
CurResultReg = NewResultReg;
Offset += LeftoverPartSize;
}
LLT ResultLCMTy = buildLCMMergePieces(ResultTy, LeftoverTy, GCDTy, GCDRegs);
buildWidenedRemergeToDst(DstReg, ResultLCMTy, GCDRegs);
}

/// Append the result registers of G_UNMERGE_VALUES \p MI to \p Regs.
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
Expand Up @@ -80,7 +80,7 @@ end:
br label %block
}

; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: cannot select: %{{[0-9]+}}:gpr32(s32), %{{[0-9]+}}:gpr(s1) = G_UADDE %{{[0-9]+}}:gpr, %{{[0-9]+}}:gpr, %{{[0-9]+}}:gpr (in function: nonpow2_add_narrowing)
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: cannot select: %{{[0-9]+}}:gpr(s32), %{{[0-9]+}}:gpr(s32) = G_UNMERGE_VALUES %{{[0-9]+}}:gpr(s64) (in function: nonpow2_add_narrowing)
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_add_narrowing
; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_add_narrowing:
define void @nonpow2_add_narrowing(i128 %x, i128 %y) {
Expand Down
690 changes: 669 additions & 21 deletions llvm/test/CodeGen/AArch64/GlobalISel/legalize-add.mir

Large diffs are not rendered by default.

0 comments on commit 31a9659

Please sign in to comment.