summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2017-02-15 23:22:33 +0000
committerTim Northover <tnorthover@apple.com>2017-02-15 23:22:33 +0000
commit4a652227dd766c2910a62e4b6c12dccb48ea9b1a (patch)
tree1e05e106e71ce54023ec59be147e9cd22e4f051a /llvm
parent3c1432fecf4a10751c24a7d38d8334c1f49c4ab8 (diff)
downloadbcm5719-llvm-4a652227dd766c2910a62e4b6c12dccb48ea9b1a.tar.gz
bcm5719-llvm-4a652227dd766c2910a62e4b6c12dccb48ea9b1a.zip
GlobalISel: support translating va_arg
Since (say) i128 and [16 x i8] map to the same type in generic MIR, we also need to attach the required alignment info. llvm-svn: 295254
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h5
-rw-r--r--llvm/include/llvm/Target/GenericOpcodes.td8
-rw-r--r--llvm/include/llvm/Target/TargetOpcodes.def3
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp12
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll13
5 files changed, 38 insertions, 3 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index 352eebd58c5..7ed2082f94d 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -300,6 +300,8 @@ private:
return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
}
+ bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder);
+
// Stubs to keep the compiler happy while we implement the rest of the
// translation.
bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) {
@@ -338,9 +340,6 @@ private:
bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) {
return false;
}
- bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder) {
- return false;
- }
bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder) {
return false;
}
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index 4c5d61788f2..880fbc46374 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -98,6 +98,14 @@ def G_VASTART : Instruction {
let mayStore = 1;
}
+def G_VAARG : Instruction {
+ let OutOperandList = (outs type0:$val);
+ let InOperandList = (ins type1:$list, unknown:$align);
+ let hasSideEffects = 0;
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+
//------------------------------------------------------------------------------
// Binary ops.
//------------------------------------------------------------------------------
diff --git a/llvm/include/llvm/Target/TargetOpcodes.def b/llvm/include/llvm/Target/TargetOpcodes.def
index b38e0cfc364..2d1ff50ca10 100644
--- a/llvm/include/llvm/Target/TargetOpcodes.def
+++ b/llvm/include/llvm/Target/TargetOpcodes.def
@@ -283,6 +283,9 @@ HANDLE_TARGET_OPCODE(G_FCONSTANT)
/// Generic va_start instruction. Stores to its one pointer operand.
HANDLE_TARGET_OPCODE(G_VASTART)
+/// Generic va_start instruction. Stores to its one pointer operand.
+HANDLE_TARGET_OPCODE(G_VAARG)
+
// Generic sign extend
HANDLE_TARGET_OPCODE(G_SEXT)
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index c5ac42f4430..e80dac1c952 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -906,6 +906,18 @@ bool IRTranslator::translateAlloca(const User &U,
return true;
}
+bool IRTranslator::translateVAArg(const User &U, MachineIRBuilder &MIRBuilder) {
+ // FIXME: We may need more info about the type. Because of how LLT works,
+ // we're completely discarding the i64/double distinction here (amongst
+ // others). Fortunately the ABIs I know of where that matters don't use va_arg
+ // anyway but that's not guaranteed.
+ MIRBuilder.buildInstr(TargetOpcode::G_VAARG)
+ .addDef(getOrCreateVReg(U))
+ .addUse(getOrCreateVReg(*U.getOperand(0)))
+ .addImm(DL->getABITypeAlignment(U.getType()));
+ return true;
+}
+
bool IRTranslator::translatePHI(const User &U, MachineIRBuilder &MIRBuilder) {
const PHINode &PI = cast<PHINode>(U);
auto MIB = MIRBuilder.buildInstr(TargetOpcode::PHI);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
index 418c71e3992..3c06d5c80f7 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
@@ -1134,6 +1134,19 @@ define void @test_va_end(i8* %list) {
ret void
}
+define void @test_va_arg(i8* %list) {
+; CHECK-LABEL: test_va_arg
+; CHECK: [[LIST:%[0-9]+]](p0) = COPY %x0
+; CHECK: G_VAARG [[LIST]](p0), 8
+; CHECK: G_VAARG [[LIST]](p0), 1
+; CHECK: G_VAARG [[LIST]](p0), 16
+
+ %v0 = va_arg i8* %list, i64
+ %v1 = va_arg i8* %list, i8
+ %v2 = va_arg i8* %list, i128
+ ret void
+}
+
declare float @llvm.pow.f32(float, float)
define float @test_pow_intrin(float %l, float %r) {
; CHECK-LABEL: name: test_pow_intrin
OpenPOWER on IntegriCloud