Hi all,

I've encountered another wrong-code bug with the store merging pass. This time 
it's in RTL.
The test gcc.target/aarch64/aapcs64/test_27.c on aarch64 merges a few __fp16 
values at GIMPLE level but
during RTL dse1 one of the constants generated gets wrongly misinterpreted from 
HImode to HFmode
by simplify_immed_subreg. The HFmode value it ends up producing is completely 
bogus.

By stepping through the code with GDB the problem is in the hunk touched by 
this patch when it
fills in an array of longs with the value bytes before passing it down to 
real_from_target.
It fills in the array by orring in each byte.

However, the array it declared to use for this doesn not get properly 
zero-initialised for modes
less that 32 bits wide (HFmode in this case). The fix in this patch is to just 
use an array initialiser
to zero it out. This makes the failure go away.

Bootstrapped and tested on aarch64, x86_64.

Ok for trunk?
Thanks,
Kyrill

2016-10-06  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>

    * simplify-rtx.c (simplify_immed_subreg): Zero-initialize tmp array
    before merging in bytes to pass down to real_from_target.
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 4bb16f896f89b06612e923a0b8db8e074b8a734c..9e7376c9f2b967d96b3195a6d9de57a543644d10 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -5906,14 +5906,12 @@ simplify_immed_subreg (machine_mode outermode, rtx op,
 	case MODE_DECIMAL_FLOAT:
 	  {
 	    REAL_VALUE_TYPE r;
-	    long tmp[MAX_BITSIZE_MODE_ANY_MODE / 32];
+	    long tmp[MAX_BITSIZE_MODE_ANY_MODE / 32] = { 0 };
 
 	    /* real_from_target wants its input in words affected by
 	       FLOAT_WORDS_BIG_ENDIAN.  However, we ignore this,
 	       and use WORDS_BIG_ENDIAN instead; see the documentation
 	       of SUBREG in rtl.texi.  */
-	    for (i = 0; i < max_bitsize / 32; i++)
-	      tmp[i] = 0;
 	    for (i = 0; i < elem_bitsize; i += value_bit)
 	      {
 		int ibase;

Reply via email to