This is an update of the patch posted to PR82089 long ago. We ran into the same bug on GCN, so we need this fixed as part of this series.
2018-09-05 Andrew Stubbs <a...@codesourcery.com> Tom de Vries <t...@codesourcery.com> PR82089 gcc/ * expmed.c (emit_cstore): Fix handling of result_mode == BImode and STORE_FLAG_VALUE == 1. --- gcc/expmed.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/gcc/expmed.c b/gcc/expmed.c index 29ce10b..0b87fdc 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -5464,11 +5464,18 @@ emit_cstore (rtx target, enum insn_code icode, enum rtx_code code, If STORE_FLAG_VALUE does not have the sign bit set when interpreted in MODE, we can do this conversion as unsigned, which is usually more efficient. */ - if (GET_MODE_SIZE (int_target_mode) > GET_MODE_SIZE (result_mode)) + if (GET_MODE_SIZE (int_target_mode) > GET_MODE_SIZE (result_mode) + || (result_mode == BImode && int_target_mode != BImode)) { - convert_move (target, subtarget, - val_signbit_known_clear_p (result_mode, - STORE_FLAG_VALUE)); + gcc_assert (GET_MODE_SIZE (result_mode) != 1 + || STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1); + bool unsignedp + = (GET_MODE_SIZE (result_mode) == 1 + ? STORE_FLAG_VALUE == 1 + : val_signbit_known_clear_p (result_mode, STORE_FLAG_VALUE)); + + convert_move (target, subtarget, unsignedp); + op0 = target; result_mode = int_target_mode; }