aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-common.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-01-05 15:13:33 +0100
committerRichard Biener <rguenther@suse.de>2022-01-10 11:29:43 +0100
commitbe59671c5624fe8bf21ddb0192e97ebdfa4db381 (patch)
treec7d5dc368bf7380f136fe20d687cb0a541f6f782 /gcc/c-family/c-common.c
parent92e114d66e93d60dcef97c66cddbae38b657d768 (diff)
downloadgcc-be59671c5624fe8bf21ddb0192e97ebdfa4db381.zip
gcc-be59671c5624fe8bf21ddb0192e97ebdfa4db381.tar.gz
gcc-be59671c5624fe8bf21ddb0192e97ebdfa4db381.tar.bz2
middle-end/101530 - fix shufflevector lowering
This makes __builtin_shufflevector lowering force the result of the BIT_FIELD_REF lowpart operation to a temporary as to fulfil the IL verifier constraint that BIT_FIELD_REFs should be always in outermost handled component position. Trying to enforce this during gimplification isn't as straight-forward as here where we know we're dealing with an rvalue. FAIL: c-c++-common/torture/builtin-shufflevector-1.c -O0 execution test 2022-01-05 Richard Biener <rguenther@suse.de> PR middle-end/101530 gcc/c-family/ * c-common.c (c_build_shufflevector): Wrap the BIT_FIELD_REF in a TARGET_EXPR to force a temporary. gcc/testsuite/ * c-c++-common/builtin-shufflevector-3.c: New testcase.
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r--gcc/c-family/c-common.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 13341fa..4a6a4ed 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1243,6 +1243,13 @@ c_build_shufflevector (location_t loc, tree v0, tree v1,
tree lpartt = build_vector_type (TREE_TYPE (ret_type), mask.length ());
ret = build3_loc (loc, BIT_FIELD_REF,
lpartt, ret, TYPE_SIZE (lpartt), bitsize_zero_node);
+ /* Wrap the lowpart operation in a TARGET_EXPR so it gets a separate
+ temporary during gimplification. See PR101530 for cases where
+ we'd otherwise end up with non-toplevel BIT_FIELD_REFs. */
+ tree tem = create_tmp_var_raw (lpartt);
+ DECL_CONTEXT (tem) = current_function_decl;
+ ret = build4 (TARGET_EXPR, lpartt, tem, ret, NULL_TREE, NULL_TREE);
+ TREE_SIDE_EFFECTS (ret) = 1;
}
if (!c_dialect_cxx () && !wrap)