This patch fixes PR target/94557, on PowerPC. It was a regression on the GCC 9 branch caused by my recent patch for PR target/93932.
The patch for 93932 was a back port from the master branch of a fix for the vec_extract built-in function. This patch fixes the case where we are optimizing a vector extract from an vector in memory to be a scalar load instead of loading the vector to a register and then doing an extract. In the tests that fail, the index for the vector extract built-in function goes outside of the bounds of the vector. In the master branch, I had made a previous change to limit the variable extraction to be valid via masking. I had done this as part of optimizing vector extracts for PC-relative addresses. When I back ported the fix for PR target/93932, I did not include this masking. I had originally only tested the fix for PR target/93932 on a little endian power8 system. The test cases that fail do not fail on a little endian power8 system, but they would fail on a little endian power9 system and also a big endian power8 system. This patch adds in the masking of the vector index that is in the master branch. I re-implemented the change for GCC 9, since the changes on the master branch are more extensive, and include PC-relative support that is not in GCC 9. I have tested this patch via compiler bootstrap and running the make check options on the following systems. There were no regressions in the run, and several of the tests that started to fail with my last patch are now fixed. Can I check this into the GCC 9 branch? little endian power8 running Linux little endian power9 running Linux big endian power8 running Linux 2020-04-13 Michael Meissner <meiss...@linux.ibm.com> PR target/94557 * config/rs6000/rs6000.c (rs6000_adjust_vec_address): Mask variable vector extract index so it does not go beyond the vector when extracting a vector element from memory. This change is a simplification of the 2020-02-03 patch that went into the trunk. --- /tmp/4XFFqK_rs6000.c 2020-04-13 15:28:33.514011024 -0500 +++ gcc/config/rs6000/rs6000.c 2020-04-13 14:24:01.296932921 -0500 @@ -7047,18 +7047,25 @@ rs6000_adjust_vec_address (rtx scalar_re element_offset = GEN_INT (INTVAL (element) * scalar_size); else { + /* Mask the element to make sure the element number is between 0 and the + maximum number of elements - 1 so that we don't generate an address + outside the vector. */ + rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (GET_MODE (mem)) - 1); + rtx and_op = gen_rtx_AND (Pmode, element, num_ele_m1); + emit_insn (gen_rtx_SET (base_tmp, and_op)); + int byte_shift = exact_log2 (scalar_size); gcc_assert (byte_shift >= 0); if (byte_shift == 0) - element_offset = element; + element_offset = base_tmp; else { if (TARGET_POWERPC64) - emit_insn (gen_ashldi3 (base_tmp, element, GEN_INT (byte_shift))); + emit_insn (gen_ashldi3 (base_tmp, base_tmp, GEN_INT (byte_shift))); else - emit_insn (gen_ashlsi3 (base_tmp, element, GEN_INT (byte_shift))); + emit_insn (gen_ashlsi3 (base_tmp, base_tmp, GEN_INT (byte_shift))); element_offset = base_tmp; } -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797