Hi! As mentioned in the PR, gimple_build can return some trees that aren't valid in MEM_REF's operand (in particular, SSA_NAMEs are allowed there, but only a subset of invariants). The following patch forces the address into a SSA_NAME if it fails the MEM_REF operand's predicate.
Bootstrapped/regtested on powerpc64{,le}-linux, preapproved in the PR by Segher, committed to trunk. 2019-01-22 Jakub Jelinek <ja...@redhat.com> PR target/88965 * config/rs6000/rs6000.c: Include tree-vrp.h and tree-ssanames.h. (rs6000_gimple_fold_builtin): If MEM_REF address doesn't satisfy is_gimple_mem_ref_addr predicate, force it into a SSA_NAME first. * gcc.target/powerpc/pr88965.c: New test. --- gcc/config/rs6000/rs6000.c.jj 2019-01-16 09:35:09.245245627 +0100 +++ gcc/config/rs6000/rs6000.c 2019-01-22 09:10:41.013386868 +0100 @@ -81,6 +81,8 @@ #include "case-cfn-macros.h" #include "ppc-auxv.h" #include "tree-ssa-propagate.h" +#include "tree-vrp.h" +#include "tree-ssanames.h" /* This file should be included last. */ #include "target-def.h" @@ -15853,6 +15855,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_ arg1_type, temp_addr, build_int_cst (arg1_type, -16)); gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + if (!is_gimple_mem_ref_addr (aligned_addr)) + { + tree t = make_ssa_name (TREE_TYPE (aligned_addr)); + gimple *g = gimple_build_assign (t, aligned_addr); + gsi_insert_before (gsi, g, GSI_SAME_STMT); + aligned_addr = t; + } /* Use the build2 helper to set up the mem_ref. The MEM_REF could also take an offset, but since we've already incorporated the offset above, here we just pass in a zero. */ @@ -15898,6 +15907,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_ arg2_type, temp_addr, build_int_cst (arg2_type, -16)); gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + if (!is_gimple_mem_ref_addr (aligned_addr)) + { + tree t = make_ssa_name (TREE_TYPE (aligned_addr)); + gimple *g = gimple_build_assign (t, aligned_addr); + gsi_insert_before (gsi, g, GSI_SAME_STMT); + aligned_addr = t; + } /* The desired gimple result should be similar to: MEM[(__vector floatD.1407 *)_1] = vf1D.2697; */ gimple *g @@ -15935,6 +15951,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_ tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR, arg1_type, arg1, temp_offset); gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + if (!is_gimple_mem_ref_addr (temp_addr)) + { + tree t = make_ssa_name (TREE_TYPE (temp_addr)); + gimple *g = gimple_build_assign (t, temp_addr); + gsi_insert_before (gsi, g, GSI_SAME_STMT); + temp_addr = t; + } /* Use the build2 helper to set up the mem_ref. The MEM_REF could also take an offset, but since we've already incorporated the offset above, here we just pass in a zero. */ @@ -15971,6 +15994,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_ tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR, arg2_type, arg2, temp_offset); gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + if (!is_gimple_mem_ref_addr (temp_addr)) + { + tree t = make_ssa_name (TREE_TYPE (temp_addr)); + gimple *g = gimple_build_assign (t, temp_addr); + gsi_insert_before (gsi, g, GSI_SAME_STMT); + temp_addr = t; + } gimple *g; g = gimple_build_assign (build2 (MEM_REF, align_stype, temp_addr, build_int_cst (arg2_type, 0)), arg0); --- gcc/testsuite/gcc.target/powerpc/pr88965.c.jj 2019-01-22 09:11:13.341858513 +0100 +++ gcc/testsuite/gcc.target/powerpc/pr88965.c 2019-01-22 09:09:21.406687888 +0100 @@ -0,0 +1,19 @@ +/* PR target/88965 */ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ + +unsigned int a[16]; +unsigned int __attribute__ ((vector_size (16))) b; + +void +foo (void) +{ + b = __builtin_vec_vsx_ld (0, &a[0]); +} + +void +bar (void) +{ + __builtin_vec_vsx_st (b, 0, &a[0]); +} Jakub