arm: Fix uaddvdi4 expander [PR93494]
authorJakub Jelinek <jakub@redhat.com>
Thu, 30 Jan 2020 11:58:20 +0000 (12:58 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 30 Jan 2020 11:58:20 +0000 (12:58 +0100)
uaddvdi4 expander has an optimization for the low 32-bits of the 2nd input
operand known to be 0.  Unfortunately, in that case it only emits copying of
the low 32 bits to the low 32 bits of the destination, but doesn't emit the
addition with overflow detection for the high 64 bits.
Well, to be precise, it emits it, but into an RTL sequence returned by
gen_uaddvsi4, but that sequence isn't emitted anywhere.

2020-01-30  Jakub Jelinek  <jakub@redhat.com>

PR target/93494
* config/arm/arm.md (uaddvdi4): Actually emit what gen_uaddvsi4
returned.

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

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr93494.c [new file with mode: 0644]

index 4beb63934bc9984ca09aefa6ab93972cbb666010..a141e0669f0dd8174fcf56ba0d0c7495b78db470 100644 (file)
@@ -1,5 +1,9 @@
 2020-01-30  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/93494
+       * config/arm/arm.md (uaddvdi4): Actually emit what gen_uaddvsi4
+       returned.
+
        PR target/91824
        * config/i386/sse.md
        (*<sse>_movmsk<ssemodesuffix><avxsizesuffix>_zext): Renamed to ...
index 0454908256727247b4d0a4f402ad234bdbf1907c..dd73263409a339a03bee97c27992b8d78c4babf3 100644 (file)
       if (!arm_add_operand (hi_op2, SImode))
        hi_op2 = force_reg (SImode, hi_op2);
 
-      gen_uaddvsi4 (hi_result, hi_op1, hi_op2, operands[3]);
+      emit_insn (gen_uaddvsi4 (hi_result, hi_op1, hi_op2, operands[3]));
     }
   else
     {
index 597788a80a325b258bf61be2ad619881075320bd..ab61b48c7bddd33fe619e3f54b9bc9ccaa2a9db9 100644 (file)
@@ -1,3 +1,8 @@
+2020-01-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/93494
+       * gcc.c-torture/execute/pr93494.c: New test.
+
 2020-01-30  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/90338
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr93494.c b/gcc/testsuite/gcc.c-torture/execute/pr93494.c
new file mode 100644 (file)
index 0000000..ef70403
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR target/93494 */
+
+unsigned short a;
+
+int
+main ()
+{
+  register unsigned long long y = 0;
+  int x = __builtin_add_overflow (y, 0ULL, &a);
+  if (x || a)
+    __builtin_abort ();
+  return 0;
+}