[expr.c] PR middle-end/71700: zero-extend sub-word value when widening constructor...
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Tue, 12 Jul 2016 15:00:28 +0000 (15:00 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Tue, 12 Jul 2016 15:00:28 +0000 (15:00 +0000)
PR middle-end/71700
* expr.c (store_constructor): Mask sign-extended bits when widening
sub-word constructor element at the start of a word.

* gcc.c-torture/execute/pr71700.c: New test.

From-SVN: r238248

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr71700.c [new file with mode: 0644]

index 509e855e95b28ae09d996a12e0f6736f78effcc4..ac411d5c3cb5a88988062f08d14e37ed27f05ea9 100644 (file)
@@ -1,3 +1,9 @@
+2016-07-12  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR middle-end/71700
+       * expr.c (store_constructor): Mask sign-extended bits when widening
+       sub-word constructor element at the start of a word.
+
 2016-07-12  Martin Liska  <mliska@suse.cz>
 
        * ira-build.c (mark_loops_for_removal): Properly iterate
index fbc91ad667fd46bfe4c6e5e8812ee12019d9ea77..4073a989d96edb5694cdae9fe50e161843d645c1 100644 (file)
@@ -6281,6 +6281,13 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size,
                    type = lang_hooks.types.type_for_mode
                      (word_mode, TYPE_UNSIGNED (type));
                    value = fold_convert (type, value);
+                   /* Make sure the bits beyond the original bitsize are zero
+                      so that we can correctly avoid extra zeroing stores in
+                      later constructor elements.  */
+                   tree bitsize_mask
+                     = wide_int_to_tree (type, wi::mask (bitsize, false,
+                                                          BITS_PER_WORD));
+                   value = fold_build2 (BIT_AND_EXPR, type, value, bitsize_mask);
                  }
 
                if (BYTES_BIG_ENDIAN)
index 7dd3c92c4fc8e17ddf9d0a42a130a7336d0d4a1b..71b52273b681d2df749f3ba1d7baaa79b6e055d3 100644 (file)
@@ -1,3 +1,8 @@
+2016-07-12  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR middle-end/71700
+       * gcc.c-torture/execute/pr71700.c: New test.
+
 2016-07-12  Steven Bosscher  <steven@gcc.gnu.org>
        Richard Biener  <rguenther@suse.de>
 
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71700.c b/gcc/testsuite/gcc.c-torture/execute/pr71700.c
new file mode 100644 (file)
index 0000000..80afd38
--- /dev/null
@@ -0,0 +1,19 @@
+struct S
+{
+  signed f0 : 16;
+  unsigned f1 : 1;
+};
+
+int b;
+static struct S c[] = {{-1, 0}, {-1, 0}};
+struct S d;
+
+int
+main ()
+{
+  struct S e = c[0];
+  d = e;
+  if (d.f1 != 0)
+    __builtin_abort ();
+  return 0;
+}