https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70467

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |uros at gcc dot gnu.org

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
As for the double word additions/subtractions with low bits 0, like:
unsigned long long
foo (unsigned long long x)
{
  return x + 0x12345600000000ULL;
}

unsigned long long
bar (unsigned long long x)
{
  return x - 0x12345600000000ULL;
}
for -m32 -O2 and
__uint128_t
foo (__uint128_t x)
{
  return x + ((__uint128_t) 123456 << 64);
}

__uint128_t
bar (__uint128_t x)
{
  return x - ((__uint128_t) 123456 << 64);
}
for -m64 -O2, I have a partial fix here:

--- gcc/config/i386/i386.md.jj  2016-03-29 19:31:23.000000000 +0200
+++ gcc/config/i386/i386.md     2016-03-31 17:33:36.848167239 +0200
@@ -5449,7 +5449,14 @@ (define_insn_and_split "*add<dwi>3_doubl
                       (match_dup 4))
                     (match_dup 5)))
              (clobber (reg:CC FLAGS_REG))])]
-  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0],
&operands[3]);")
+{
+  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
+  if (operands[2] == const0_rtx)
+    {
+      ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
+      DONE;
+    }
+})

 (define_insn "*add<mode>_1"
   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
@@ -6379,7 +6386,14 @@ (define_insn_and_split "*sub<dwi>3_doubl
                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
                     (match_dup 5)))
              (clobber (reg:CC FLAGS_REG))])]
-  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0],
&operands[3]);")
+{
+  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
+  if (operands[2] == const0_rtx)
+    {
+      ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
+      DONE;
+    }
+})

 (define_insn "*sub<mode>_1"
   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")

but it only works for the -m32 testcase.  The problem is that for "<di>" for
the TImode addition/subtraction we use "e" constraint and that is obviously
inappropriate, we want some new constraints that makes sure that both the low
and high 64-bits of the constant are "e".  Will hack on that tomorrow.

Reply via email to