]> granicus.if.org Git - llvm/commitdiff
GlobalISel: support translating va_arg
authorTim Northover <tnorthover@apple.com>
Wed, 15 Feb 2017 23:22:33 +0000 (23:22 +0000)
committerTim Northover <tnorthover@apple.com>
Wed, 15 Feb 2017 23:22:33 +0000 (23:22 +0000)
Since (say) i128 and [16 x i8] map to the same type in generic MIR, we also
need to attach the required alignment info.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295254 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/GlobalISel/IRTranslator.h
include/llvm/Target/GenericOpcodes.td
include/llvm/Target/TargetOpcodes.def
lib/CodeGen/GlobalISel/IRTranslator.cpp
test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

index 352eebd58c5d992d1080650b6f844c81fb86333a..7ed2082f94d961f629f550f3386101afde404ee0 100644 (file)
@@ -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;
   }
index 4c5d61788f2663d0ea9e01ffe26e68317a251c3d..880fbc46374ed94e4cac2b5e4576db0deecfb6ee 100644 (file)
@@ -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.
 //------------------------------------------------------------------------------
index b38e0cfc3647275680e8d19c75eabae8e57323f8..2d1ff50ca107d3de089124880809774320b04bcc 100644 (file)
@@ -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)
 
index c5ac42f44305ec218b786c58b9d05b9666a8d978..e80dac1c952bc03fe7e1a32e5f9f8e39f6e89d73 100644 (file)
@@ -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);
index 418c71e3992d0ac38e24667035c17bb84323a6ee..3c06d5c80f7b10135510e86539b77f08a0528423 100644 (file)
@@ -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