From 14014b55d1c42964f5c22a65822c30906b72e96b Mon Sep 17 00:00:00 2001
From: Simon Schuster <git@rationality.eu>
Date: Sun, 21 May 2017 20:52:26 +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

This commit catches up to a matching bugfix in patmos-llvm.

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.
---
 lib/CodeGen/CGStmt.cpp | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 33dad27264..b748e75827 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -497,18 +497,22 @@ void CodeGenFunction::EmitPlatinaIntrinsic(const ArrayRef<const Attr*> &Attrs) {
     // Skip non PlatinaGuard attributes
     if (!PA) continue;
 
-    Function *Callee =
-      CGM.getIntrinsic(Intrinsic::platina);
-    CallInst *callsite = Builder.CreateCall(Callee);
-
     // Attach the guardexpr to the instruction-metadata
     // We have to store our string in the LLVMContext
-    LLVMContext& C = callsite->getContext();
-    StringRef name = PA->getType()->getName();
-    MDNode *type = MDNode::get(C, MDString::get(C, name));
-    callsite->setMetadata("platina.type", type);
-    MDNode *expr = MDNode::get(C, MDString::get(C, PA->getPlatinaExpr()));
-    callsite->setMetadata("platina.expr", expr);
+    LLVMContext& C = Builder.getContext();
+
+    // In theory, we could wrap a plain MDString into a MetadataAsValue
+    // However, we need MDNodes as MachnineInstrunctions anyways, so,
+    // for consistencies sake, we marshal MDNodes the whole way
+    StringRef name         = PA->getType()->getName();
+    MDNode *type           = MDNode::get(C, MDString::get(C, name));
+    MetadataAsValue *vtype = MetadataAsValue::get(C, type);
+    MDNode *expr           = MDNode::get(C, MDString::get(C, PA->getPlatinaExpr()));
+    MetadataAsValue *vexpr = MetadataAsValue::get(C, expr);
+
+    Function *Callee =
+      CGM.getIntrinsic(Intrinsic::platina);
+    Builder.CreateCall(Callee, {vtype, vexpr});
   }
 }
 
-- 
GitLab