Hello! Attached patch fixes oversight with AND pattern and 0xffffffff immediate. While ANDs with 0xff and 0xffff are converted to equivalent zero_extend pattern, AND with 0xffffffff isn't. This problem leaves important optimization that would substitute "movq %rdi, %rax; andl $4294967295, %eax" sequence with "movl %edi, %eax" ineffective.
This optimization happens ~100 times in cc1. Moving to stage4 got me by a bit of surprise (I was away from the keyboard for the weekend), so I will leave to RMs if this (otherwise fairly safe patch) is OK for mainline. 2012-01-09 Uros Bizjak <ubiz...@gmail.com> PR target/51681 * config/i386/constraints.md ("L"): Return true for 0xffffffff. * config/i386/i386.c (*anddi_1): Emit AND with 0xffffffff as MOV. So, OK for mainline? Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 183014) +++ config/i386/i386.md (working copy) @@ -7678,19 +7678,23 @@ enum machine_mode mode; gcc_assert (CONST_INT_P (operands[2])); - if (INTVAL (operands[2]) == 0xff) - mode = QImode; + if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff) + mode = SImode; + else if (INTVAL (operands[2]) == 0xffff) + mode = HImode; else { - gcc_assert (INTVAL (operands[2]) == 0xffff); - mode = HImode; + gcc_assert (INTVAL (operands[2]) == 0xff); + mode = QImode; } operands[1] = gen_lowpart (mode, operands[1]); - if (mode == QImode) + if (mode == SImode) + return "mov{l}\t{%1, %k0|%k0, %1}"; + else if (mode == HImode) + return "movz{wl|x}\t{%1, %k0|%k0, %1}"; + else return "movz{bl|x}\t{%1, %k0|%k0, %1}"; - else - return "movz{wl|x}\t{%1, %k0|%k0, %1}"; } default: @@ -7726,19 +7730,19 @@ enum machine_mode mode; gcc_assert (CONST_INT_P (operands[2])); - if (INTVAL (operands[2]) == 0xff) - mode = QImode; + if (INTVAL (operands[2]) == 0xffff) + mode = HImode; else { - gcc_assert (INTVAL (operands[2]) == 0xffff); - mode = HImode; + gcc_assert (INTVAL (operands[2]) == 0xff); + mode = QImode; } operands[1] = gen_lowpart (mode, operands[1]); - if (mode == QImode) + if (mode == HImode) + return "movz{wl|x}\t{%1, %0|%0, %1}"; + else return "movz{bl|x}\t{%1, %0|%0, %1}"; - else - return "movz{wl|x}\t{%1, %0|%0, %1}"; } default: Index: config/i386/constraints.md =================================================================== --- config/i386/constraints.md (revision 183014) +++ config/i386/constraints.md (working copy) @@ -149,9 +149,11 @@ (match_test "IN_RANGE (ival, -128, 127)"))) (define_constraint "L" - "@code{0xFF} or @code{0xFFFF}, for andsi as a zero-extending move." + "@code{0xFF}, @code{0xFFFF} or @code{0xFFFFFFFF} + for AND as a zero-extending move." (and (match_code "const_int") - (match_test "ival == 0xFF || ival == 0xFFFF"))) + (match_test "ival == 0xff || ival == 0xffff + || ival == (HOST_WIDE_INT) 0xffffffff"))) (define_constraint "M" "0, 1, 2, or 3 (shifts for the @code{lea} instruction)."