diff options
author | Richard Biener <rguenther@suse.de> | 2022-01-05 15:13:33 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2022-01-10 11:29:43 +0100 |
commit | be59671c5624fe8bf21ddb0192e97ebdfa4db381 (patch) | |
tree | c7d5dc368bf7380f136fe20d687cb0a541f6f782 /gcc | |
parent | 92e114d66e93d60dcef97c66cddbae38b657d768 (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/c-family/c-common.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/builtin-shufflevector-3.c | 15 |
2 files changed, 22 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) diff --git a/gcc/testsuite/c-c++-common/builtin-shufflevector-3.c b/gcc/testsuite/c-c++-common/builtin-shufflevector-3.c new file mode 100644 index 0000000..0c9bda6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/builtin-shufflevector-3.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +typedef int __attribute__((__vector_size__ (sizeof(int)*4))) V; + +int +foo(V v, int i) +{ + return __builtin_shufflevector (v, v, 2, 3)[i]; +} + +int +bar(V v, int i) +{ + return __builtin_shufflevector(v, v, 4)[0] & i; +} |