Make indirect ret work
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index da79e70..ccbc1c3 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -678,7 +678,7 @@
   if (is_indirect_return)
   {
     func_return_type = build_variant_type_copy (func_return_type);
-    TREE_ADDRESSABLE (func_return_type) = 1;
+    //TREE_ADDRESSABLE (func_return_type) = 1;
   }
 
   tree *arg_types = (tree *)xcalloc(params->length (), sizeof(tree*));
@@ -703,6 +703,13 @@
 
   tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL,
 			     NULL_TREE, func_return_type);
+  if (is_indirect_return)
+  {
+    fprintf (stderr, "Indirect return\n");
+    DECL_BY_REFERENCE (resdecl) = 1;
+    TREE_TYPE (resdecl) = build_reference_type (TREE_TYPE (resdecl));
+    relayout_decl (resdecl);
+  }
   DECL_ARTIFICIAL (resdecl) = 1;
   DECL_IGNORED_P (resdecl) = 1;
   DECL_RESULT (fndecl) = resdecl;
@@ -820,7 +827,7 @@
   }
 
   decl_attributes (&fndecl, fn_attributes, 0);
-  function *func = new function (this, fndecl, kind);
+  function *func = new function (this, fndecl, kind, is_indirect_return);
   m_functions.safe_push (func);
   return func;
 }
@@ -2271,12 +2278,14 @@
 playback::function::
 function (context *ctxt,
 	  tree fndecl,
-	  enum gcc_jit_function_kind kind)
+	  enum gcc_jit_function_kind kind,
+	  bool is_indirect_return)
 : m_ctxt(ctxt),
   m_inner_fndecl (fndecl),
   m_inner_bind_expr (NULL),
   m_kind (kind),
-  m_blocks ()
+  m_blocks (),
+  m_has_indirect_return (is_indirect_return)
 {
   if (m_kind != GCC_JIT_FUNCTION_IMPORTED)
     {
@@ -2740,14 +2749,28 @@
     {
       tree t_lvalue = DECL_RESULT (m_func->as_fndecl ());
       tree t_rvalue = rvalue->as_tree ();
-      if (TREE_TYPE (t_rvalue) != TREE_TYPE (t_lvalue))
-	t_rvalue = build1 (CONVERT_EXPR,
-			   TREE_TYPE (t_lvalue),
-			   t_rvalue);
-      modify_retval = build2 (MODIFY_EXPR, return_type,
-			      t_lvalue, t_rvalue);
-      if (loc)
-	set_tree_location (modify_retval, loc);
+      if (m_func->m_has_indirect_return)
+      {
+          tree type = TREE_TYPE (TREE_TYPE(t_lvalue));
+          tree datum = fold_build1 (INDIRECT_REF, type, t_lvalue);
+          tree stmt =
+              build2 (MODIFY_EXPR, type,
+                      datum, t_rvalue);
+          if (loc)
+              set_tree_location (stmt, loc);
+          add_stmt (stmt);
+      }
+      else
+      {
+          if (TREE_TYPE (t_rvalue) != TREE_TYPE (t_lvalue))
+              t_rvalue = build1 (CONVERT_EXPR,
+                      TREE_TYPE (t_lvalue),
+                      t_rvalue);
+          modify_retval = build2 (MODIFY_EXPR, return_type,
+                  t_lvalue, t_rvalue);
+          if (loc)
+              set_tree_location (modify_retval, loc);
+      }
     }
   tree return_stmt = build1 (RETURN_EXPR, return_type,
 			     modify_retval);
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index c094400..87ac0a2 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -579,7 +579,7 @@
 class function : public wrapper
 {
 public:
-  function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
+  function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind, bool is_indirect_return);
 
   void gt_ggc_mx ();
   void finalizer () final override;
@@ -621,6 +621,7 @@
   {
     m_ctxt->set_tree_location (t, loc);
   }
+  bool m_has_indirect_return;
 
 private:
   tree m_inner_fndecl;