aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2020-10-15 13:39:41 -0700
committerAndres Freund <andres@anarazel.de>2020-10-15 15:06:16 -0700
commitf3dee5b9aba6bd8cf3d5a13296495df7b273835c (patch)
treee6b32f219f6cd6d5b6aa3998ad0eb8fbd4bba368
parent3c4b5206850263ec0585db60bf5d17187b0dd513 (diff)
downloadpostgresql-f3dee5b9aba6bd8cf3d5a13296495df7b273835c.tar.gz
postgresql-f3dee5b9aba6bd8cf3d5a13296495df7b273835c.zip
llvmjit: Also copy parameter / return value attributes from template functions.
Previously we only copied the function attributes. That caused problems at least on s390x: Because we didn't copy the 'zeroext' attribute for ExecAggTransReparent()'s *IsNull parameters, expressions invoking it didn't ensure that the upper bytes of the registers were zeroed. In the - relatively rare - cases where not, ExecAggTransReparent() wrongly ended up in the newValueIsNull branch due to the register not being zero. Subsequently causing a crash. It's quite possible that this would cause problems on other platforms, and in other places than just ExecAggTransReparent() on s390x. Thanks to Christoph (and the Debian project) for providing me with access to a s390x machine, allowing me to debug this. Reported-By: Christoph Berg Author: Andres Freund Discussion: https://postgr.es/m/20201015083246.kie5726xerdt3ael@alap3.anarazel.de Backpatch: 11-, where JIT was added
-rw-r--r--src/backend/jit/llvm/llvmjit.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index 7510698f863..c401a1c5b48 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -327,26 +327,48 @@ llvm_get_decl(LLVMModuleRef mod, LLVMValueRef v_src)
}
/*
- * Copy attributes from one function to another.
+ * Copy attributes from one function to another, for a specific index (an
+ * index can reference return value, function and parameter attributes).
*/
-void
-llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
+static void
+llvm_copy_attributes_at_index(LLVMValueRef v_from, LLVMValueRef v_to, uint32 index)
{
int num_attributes;
- int attno;
LLVMAttributeRef *attrs;
+ int attno;
- num_attributes =
- LLVMGetAttributeCountAtIndex(v_from, LLVMAttributeFunctionIndex);
+ num_attributes = LLVMGetAttributeCountAtIndex(v_from, index);
attrs = palloc(sizeof(LLVMAttributeRef) * num_attributes);
- LLVMGetAttributesAtIndex(v_from, LLVMAttributeFunctionIndex, attrs);
+ LLVMGetAttributesAtIndex(v_from, index, attrs);
for (attno = 0; attno < num_attributes; attno++)
- {
- LLVMAddAttributeAtIndex(v_to, LLVMAttributeFunctionIndex,
- attrs[attno]);
- }
+ LLVMAddAttributeAtIndex(v_to, index, attrs[attno]);
+
+ pfree(attrs);
+}
+
+/*
+ * Copy all attributes from one function to another. I.e. function, return and
+ * parameters will be copied.
+ */
+void
+llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
+{
+ uint32 param_count;
+ int paramidx;
+
+ /* copy function attributes */
+ llvm_copy_attributes_at_index(v_from, v_to, LLVMAttributeFunctionIndex);
+
+ /* and the return value attributes */
+ llvm_copy_attributes_at_index(v_from, v_to, LLVMAttributeReturnIndex);
+
+ /* and each function parameter's attribute */
+ param_count = LLVMCountParams(v_from);
+
+ for (paramidx = 1; paramidx <= param_count; paramidx++)
+ llvm_copy_attributes_at_index(v_from, v_to, paramidx);
}
/*