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.