[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc-bugs
Subject:    [Bug rtl-optimization/70467] Useless "and [esp],-1" emitted on AND with uint64_t variable
From:       "jakub at gcc dot gnu.org" <gcc-bugzilla () gcc ! gnu ! org>
Date:       2016-03-31 15:51:05
Message-ID: bug-70467-4-OrrbH8pAI2 () http ! gcc ! gnu ! org/bugzilla/
[Download RAW message or body]

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.=
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic