Hi, now that we regard MEM_EXPR as a conservative approximation for MEM_SIZE (and MEM_OFFSET) we must ensure that this is really the case. It isn't currently for the string expanders, as they use the MEM_REF (whose address was taken) directly as the one to use for MEM_EXPR on the MEM rtx. That's wrong, on gimple side we take the address only and hence its size is arbitrary.
So, we have to build a memref always and rewrite its type to one representing the real size. Note that TYPE_MAX_VALUE may be NULL, so we don't need to check for 'len' being null or not. This fixes the C testcase (don't know about fma 3d), and is in regstrapping on x86_64-linux. Okay if that passes? Ciao, Michael. PR middle-end/53688 * builtins.c (get_memory_rtx): Always build a MEM_REF and override its type with one of correct range. testsuite/ * gcc.c-torture/execute/pr53688.c: New test. Index: builtins.c =================================================================== --- builtins.c (revision 188734) +++ builtins.c (working copy) @@ -1274,11 +1274,11 @@ get_memory_rtx (tree exp, tree len) && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR && host_integerp (TREE_OPERAND (exp, 1), 0) && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0) - exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + exp = build_simple_mem_ref (TREE_OPERAND (exp, 0)); else if (TREE_CODE (exp) == ADDR_EXPR) - exp = TREE_OPERAND (exp, 0); + exp = build_simple_mem_ref (exp); else if (POINTER_TYPE_P (TREE_TYPE (exp))) - exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp); + exp = build_simple_mem_ref (exp); else exp = NULL; @@ -1287,6 +1287,11 @@ get_memory_rtx (tree exp, tree len) (as stringops may access multiple array elements). */ if (exp) { + /* Reset the type to something spanning the whole thing. EXP + is always a MEM_REF, hence unshared. */ + TREE_TYPE (exp) + = build_array_type (char_type_node, + build_range_type (sizetype, size_one_node, len)); set_mem_attributes (mem, exp, 0); if (off) Index: testsuite/gcc.c-torture/execute/pr53688.c =================================================================== --- testsuite/gcc.c-torture/execute/pr53688.c (revision 0) +++ testsuite/gcc.c-torture/execute/pr53688.c (revision 0) @@ -0,0 +1,32 @@ +char headline[256]; +struct hdr { + char part1[9]; + char part2[8]; +} p; + +void __attribute__((noinline,noclone)) +init() +{ + __builtin_memcpy (p.part1, "FOOBARFOO", sizeof (p.part1)); + __builtin_memcpy (p.part2, "SPEC CPU", sizeof (p.part2)); +} + +int main() +{ + char *x; + int c; + init(); + __builtin_memcpy (&headline[0], p.part1, 9); + c = 9; + x = &headline[0]; + x = x + c; + __builtin_memset (x, ' ', 245); + __builtin_memcpy (&headline[10], p.part2, 8); + c = 18; + x = &headline[0]; + x = x + c; + __builtin_memset (x, ' ', 238); + if (headline[10] != 'S') + __builtin_abort (); + return 0; +}