From ca62919afb90788dd251a7f45c88e2bda3ef549f Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Mon, 6 Mar 2017 19:04:17 +0000 Subject: [PATCH] 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 --- .../CodeGen/GlobalISel/MachineIRBuilder.h | 3 +++ lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 25 +++++++++++++++++++ .../AArch64/GlobalISel/arm64-irtranslator.ll | 20 +++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 4eafe88831a..e3880f0834b 100644 --- a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -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. diff --git a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 08f29f4621c..1b7c7a6e52b 100644 --- a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -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 Results, ArrayRef Indices, unsigned Src) { @@ -462,6 +482,11 @@ MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef 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) diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index a05c4a8fe41..65a1422c360 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -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