aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-06-21 09:31:30 +0200
committerRichard Biener <rguenther@suse.de>2023-11-29 13:26:31 +0100
commitb09b879e4e9cc24a5d2b0344c1930020c218a104 (patch)
treea1f5d2ea70bb7a6bad4a32ce5f45e61e7dd653d7 /gcc
parent5c95bf945c632925efba86dd5dceccdb9da8884c (diff)
downloadgcc-b09b879e4e9cc24a5d2b0344c1930020c218a104.zip
gcc-b09b879e4e9cc24a5d2b0344c1930020c218a104.tar.gz
gcc-b09b879e4e9cc24a5d2b0344c1930020c218a104.tar.bz2
middle-end/110237 - wrong MEM_ATTRs for partial loads/stores
The following addresses a miscompilation by RTL scheduling related to the representation of masked stores. For that we have (insn 38 35 39 3 (set (mem:V16SI (plus:DI (reg:DI 40 r12 [orig:90 _22 ] [90]) (const:DI (plus:DI (symbol_ref:DI ("b") [flags 0x2] <var_decl 0x7ffff6e28d80 b>) (const_int -4 [0xfffffffffffffffc])))) [1 MEM <vector(16) int> [(int *)vectp_b.12_28]+0 S64 A32]) (vec_merge:V16SI (reg:V16SI 20 xmm0 [118]) (mem:V16SI (plus:DI (reg:DI 40 r12 [orig:90 _22 ] [90]) (const:DI (plus:DI (symbol_ref:DI ("b") [flags 0x2] <var_decl 0x7ffff6e28d80 b>) (const_int -4 [0xfffffffffffffffc])))) [1 MEM <vector(16) int> [(int *)vectp_b.12_28]+0 S64 A32]) and specifically the memory attributes [1 MEM <vector(16) int> [(int *)vectp_b.12_28]+0 S64 A32] are problematic. They tell us the instruction stores and reads a full vector which it if course does not. There isn't any good MEM_EXPR we can use here (we lack a way to just specify a pointer and restrict info for example), and since the MEMs have a vector mode it's difficult in general as passes do not need to look at the memory attributes at all. The easiest way to avoid running into the alias analysis problem is to scrap the MEM_EXPR when we expand the internal functions for partial loads/stores. That avoids the disambiguation we run into which is realizing that we store to an object of less size as the size of the mode we appear to store. After the patch we see just [1 S64 A32] so we preserve the alias set, the alignment and the size (the size is redundant if the MEM insn't BLKmode). That's still not good in case the RTL alias oracle would implement the same disambiguation but it fends off the gimple one. This fixes gcc.dg/torture/pr58955-2.c when built with AVX512 and --param=vect-partial-vector-usage=1. PR middle-end/110237 * internal-fn.cc (expand_partial_load_optab_fn): Clear MEM_EXPR and MEM_OFFSET. (expand_partial_store_optab_fn): Likewise.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/internal-fn.cc8
1 files changed, 8 insertions, 0 deletions
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index cce73b3..cb4ef44 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -2976,6 +2976,10 @@ expand_partial_load_optab_fn (internal_fn ifn, gcall *stmt, convert_optab optab)
mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
gcc_assert (MEM_P (mem));
+ /* The built MEM_REF does not accurately reflect that the load
+ is only partial. Clear it. */
+ set_mem_expr (mem, NULL_TREE);
+ clear_mem_offset (mem);
target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
create_output_operand (&ops[i++], target, TYPE_MODE (type));
create_fixed_operand (&ops[i++], mem);
@@ -3019,6 +3023,10 @@ expand_partial_store_optab_fn (internal_fn ifn, gcall *stmt, convert_optab optab
mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
gcc_assert (MEM_P (mem));
+ /* The built MEM_REF does not accurately reflect that the store
+ is only partial. Clear it. */
+ set_mem_expr (mem, NULL_TREE);
+ clear_mem_offset (mem);
reg = expand_normal (rhs);
create_fixed_operand (&ops[i++], mem);
create_input_operand (&ops[i++], reg, TYPE_MODE (type));