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.
This commit is contained in:
Richard Biener 2022-01-05 15:13:33 +01:00
parent 92e114d66e
commit be59671c56
2 changed files with 22 additions and 0 deletions

View file

@ -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)

View file

@ -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;
}