Hi! The /* Given (xor (ior (xor A B) C) D), where B, C and D are constants, simplify to (xor (ior A C) (B&~C)^D), canceling out bits inverted twice and not set by C. Similarly, given (xor (and (xor A B) C) D), simplify without inverting C in the xor operand: (xor (and A C) (B&C)^D). */ comment describes the intended optimization correctly, but unfortunately the code diverges from it, using (xor (and A C) (B&~C)^D) for the second and (xor (ior A C) (B&C)^D) for the first one.
Fixed thusly, committed as obvious after bootstrapping/regtesting it on x86_64-linux and i686-linux. 2015-02-06 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/64957 PR debug/64817 * simplify-rtx.c (simplify_binary_operation_1): Use ~cval for IOR rather than for AND. * gcc.c-torture/execute/pr64957.c: New test. --- gcc/simplify-rtx.c.jj 2015-02-04 15:24:20.000000000 +0100 +++ gcc/simplify-rtx.c 2015-02-06 09:41:31.139326554 +0100 @@ -2731,9 +2731,9 @@ simplify_binary_operation_1 (enum rtx_co HOST_WIDE_INT xcval; if (op == IOR) - xcval = cval; - else xcval = ~cval; + else + xcval = cval; return simplify_gen_binary (XOR, mode, simplify_gen_binary (op, mode, a, c), --- gcc/testsuite/gcc.c-torture/execute/pr64957.c.jj 2015-02-06 09:43:12.595616710 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr64957.c 2015-02-06 09:43:26.361384715 +0100 @@ -0,0 +1,23 @@ +/* PR rtl-optimization/64957 */ + +__attribute__((noinline, noclone)) int +foo (int b) +{ + return (((b ^ 5) | 1) ^ 5) | 1; +} + +__attribute__((noinline, noclone)) int +bar (int b) +{ + return (((b ^ ~5) & ~1) ^ ~5) & ~1; +} + +int +main () +{ + int i; + for (i = 0; i < 16; i++) + if (foo (i) != (i | 1) || bar (i) != (i & ~1)) + __builtin_abort (); + return 0; +} Jakub