From 3f8fbb0873f92eeb331f8b9bf39f030746c0bc67 Mon Sep 17 00:00:00 2001
From: Simon Schuster <git@rationality.eu>
Date: Sun, 21 May 2017 20:44:59 +0200
Subject: [PATCH] Bugfix: Platina-Intrinsic: pass type/expr by operand
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The former implementation passed the platina type and expression
infromation by means of two metadata items attached to the intrinsic
call instruction. However, the tail-call-optimization dropped this
metadata (in sync with the docs):

  A transformation is required to drop any metadata attachment that it
  does not know or know it can’t preserve.

Passing this data by means of operands to the call instruction should
be more robust.
---
 include/llvm/IR/Intrinsics.td                    | 2 +-
 lib/CodeGen/PMLExport.cpp                        | 4 ++--
 lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index fb66085915a..9840516a266 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -592,7 +592,7 @@ def int_debugtrap : Intrinsic<[]>,
 def int_loopbound : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty]>;
 
 // Platina annotation intrinsic - hold metadata
-def int_platina : Intrinsic<[]>;
+def int_platina : Intrinsic<[], [llvm_metadata_ty, llvm_metadata_ty]>;
 
 // NOP: calls/invokes to this intrinsic are removed by codegen
 def int_donothing : Intrinsic<[], [], [IntrNoMem]>;
diff --git a/lib/CodeGen/PMLExport.cpp b/lib/CodeGen/PMLExport.cpp
index dcf1d0736fc..37f43506c96 100644
--- a/lib/CodeGen/PMLExport.cpp
+++ b/lib/CodeGen/PMLExport.cpp
@@ -411,8 +411,8 @@ void PMLBitcodeExport::exportInstruction(yaml::Instruction* I,
       case Intrinsic::platina:
         {
           const BasicBlock *BB = II->getParent();
-          const MDNode *ntype = CI->getMetadata("platina.type");
-          const MDNode *nexpr = CI->getMetadata("platina.expr");
+          const MDNode *ntype = cast<MDNode>(cast<MetadataAsValue>(CI->getArgOperand(0))->getMetadata());
+          const MDNode *nexpr = cast<MDNode>(cast<MetadataAsValue>(CI->getArgOperand(1))->getMetadata());
           assert(ntype && nexpr &&
               "Platina intrinsic expects platina.type and platina.expr metadata");
           MDString *type = cast<MDString>(ntype->getOperand(0));
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index cefe5c02e96..799d9437ff1 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4893,8 +4893,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
     return 0;
   }
   case Intrinsic::platina: {
-    SDValue type = DAG.getMDNode(I.getMetadata("platina.type"));
-    SDValue expr = DAG.getMDNode(I.getMetadata("platina.expr"));
+    SDValue type = DAG.getMDNode(cast<MDNode>(cast<MetadataAsValue>(I.getArgOperand(0))->getMetadata()));
+    SDValue expr = DAG.getMDNode(cast<MDNode>(cast<MetadataAsValue>(I.getArgOperand(1))->getMetadata()));
     DAG.setRoot(DAG.getNode(ISD::PLATINA, sdl, MVT::Other, getRoot(), type, expr));
     return 0;
   }
-- 
GitLab