mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-02 17:58:36 +00:00
GlobalISel: don't emit degenerate G_INSERT instructions.
Before, we were producing G_INSERT instructions that were actually closer to a cast or even a COPY when both input and output sizes are the same. This doesn't really make sense and means that everything interpreting a G_INSERT also has to handle all these kinds of casts. So now we detect these degenerate cases and emit real casts instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297051 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f0a0c2348e
commit
ca62919afb
@ -338,6 +338,9 @@ public:
|
||||
/// \return The newly created instruction.
|
||||
MachineInstrBuilder buildZExtOrTrunc(unsigned Res, unsigned Op);
|
||||
|
||||
/// Build and insert an appropriate cast between two registers of equal size.
|
||||
MachineInstrBuilder buildCast(unsigned Dst, unsigned Src);
|
||||
|
||||
/// Build and insert G_BR \p Dest
|
||||
///
|
||||
/// G_BR is an unconditional branch to \p Dest.
|
||||
|
@ -362,6 +362,26 @@ MachineInstrBuilder MachineIRBuilder::buildZExtOrTrunc(unsigned Res,
|
||||
return buildInstr(Opcode).addDef(Res).addUse(Op);
|
||||
}
|
||||
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildCast(unsigned Dst, unsigned Src) {
|
||||
LLT SrcTy = MRI->getType(Src);
|
||||
LLT DstTy = MRI->getType(Dst);
|
||||
if (SrcTy == DstTy)
|
||||
return buildCopy(Dst, Src);
|
||||
|
||||
unsigned Opcode;
|
||||
if (SrcTy.isPointer() && DstTy.isScalar())
|
||||
Opcode = TargetOpcode::G_PTRTOINT;
|
||||
else if (DstTy.isPointer() && SrcTy.isScalar())
|
||||
Opcode = TargetOpcode::G_INTTOPTR;
|
||||
else {
|
||||
assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet");
|
||||
Opcode = TargetOpcode::G_BITCAST;
|
||||
}
|
||||
|
||||
return buildInstr(Opcode).addDef(Dst).addUse(Src);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<unsigned> Results,
|
||||
ArrayRef<uint64_t> Indices,
|
||||
unsigned Src) {
|
||||
@ -462,6 +482,11 @@ MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<unsigned> Res,
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildInsert(unsigned Res, unsigned Src,
|
||||
unsigned Op, unsigned Index) {
|
||||
if (MRI->getType(Res).getSizeInBits() == MRI->getType(Op).getSizeInBits()) {
|
||||
assert(Index == 0 && "insertion past the end of a register");
|
||||
return buildCast(Res, Op);
|
||||
}
|
||||
|
||||
return buildInstr(TargetOpcode::G_INSERT)
|
||||
.addDef(Res)
|
||||
.addUse(Src)
|
||||
|
@ -890,6 +890,26 @@ define void @test_insertvalue(%struct.nested* %addr, i32 %val) {
|
||||
ret void
|
||||
}
|
||||
|
||||
define [1 x i64] @test_trivial_insert([1 x i64] %s, i64 %val) {
|
||||
; CHECK-LABEL: name: test_trivial_insert
|
||||
; CHECK: [[STRUCT:%[0-9]+]](s64) = COPY %x0
|
||||
; CHECK: [[VAL:%[0-9]+]](s64) = COPY %x1
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = COPY [[VAL]](s64)
|
||||
; CHECK: %x0 = COPY [[RES]]
|
||||
%res = insertvalue [1 x i64] %s, i64 %val, 0
|
||||
ret [1 x i64] %res
|
||||
}
|
||||
|
||||
define [1 x i8*] @test_trivial_insert_ptr([1 x i8*] %s, i8* %val) {
|
||||
; CHECK-LABEL: name: test_trivial_insert_ptr
|
||||
; CHECK: [[STRUCT:%[0-9]+]](s64) = COPY %x0
|
||||
; CHECK: [[VAL:%[0-9]+]](p0) = COPY %x1
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_PTRTOINT [[VAL]](p0)
|
||||
; CHECK: %x0 = COPY [[RES]]
|
||||
%res = insertvalue [1 x i8*] %s, i8* %val, 0
|
||||
ret [1 x i8*] %res
|
||||
}
|
||||
|
||||
; CHECK-LABEL: name: test_insertvalue_agg
|
||||
; CHECK: [[SMALLSTRUCT:%[0-9]+]](s64) = G_LOAD
|
||||
; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD
|
||||
|
Loading…
Reference in New Issue
Block a user