[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351 Richard Biener rguenth at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2015-08-26 Ever confirmed|0 |1 --- Comment #6 from Richard Biener rguenth at gcc dot gnu.org --- Yes, N N can be converted (but only for unsigned right shift or in VRP with range information). Convert the following fold-const.c code to match.pd: /* Transform (x c) c into x (-1c), or transform (x c) c into x ((unsigned)-1 c) for unsigned types. */ if (((code == LSHIFT_EXPR TREE_CODE (arg0) == RSHIFT_EXPR) || (TYPE_UNSIGNED (type) code == RSHIFT_EXPR TREE_CODE (arg0) == LSHIFT_EXPR)) tree_fits_uhwi_p (arg1) tree_to_uhwi (arg1) prec tree_fits_uhwi_p (TREE_OPERAND (arg0, 1)) tree_to_uhwi (TREE_OPERAND (arg0, 1)) prec) { HOST_WIDE_INT low0 = tree_to_uhwi (TREE_OPERAND (arg0, 1)); HOST_WIDE_INT low1 = tree_to_uhwi (arg1); tree lshift; tree arg00; if (low0 == low1) { arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); lshift = build_minus_one_cst (type); lshift = const_binop (code, lshift, arg1); return fold_build2_loc (loc, BIT_AND_EXPR, type, arg00, lshift); } }
[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351 Uroš Bizjak ubizjak at gmail dot com changed: What|Removed |Added CC||rguenth at gcc dot gnu.org, ||ubizjak at gmail dot com --- Comment #3 from Uroš Bizjak ubizjak at gmail dot com --- (In reply to Uroš Bizjak from comment #2) (In reply to Allan Jensen from comment #0) Gcc will expand and detect field setting on 32-bit integers, but for some reason miss the opportunity on 64-bit. The immediates for 64bit logic insns are limited to sign-extended 32bit values, so this probably limits combine to combine several insns into one. One example is: (insn 8 6 9 2 (parallel [ (set (reg:DI 100) (lshiftrt:DI (reg/v:DI 98 [ a ]) (const_int 48 [0x30]))) (clobber (reg:CC 17 flags)) ]) test.cpp:63 538 {*lshrdi3_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) (insn 9 8 10 2 (parallel [ (set (reg:DI 101) (ashift:DI (reg:DI 100) (const_int 48 [0x30]))) (clobber (reg:CC 17 flags)) ]) test.cpp:63 504 {*ashldi3_1} (expr_list:REG_DEAD (reg:DI 100) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil combine tries to: Trying 8 - 9: Failed to match this instruction: (parallel [ (set (reg:DI 101) (and:DI (reg/v:DI 98 [ a ]) (const_int -281474976710656 [0x]))) (clobber (reg:CC 17 flags)) ]) However, tree optimizers pass to expand the following sequence: a = giveMe64 (); a$rgba_5 = MEM[(struct MyRgba64 *)a]; _6 = a$rgba_5 16; _7 = a$rgba_5 48; _8 = _7 48; _10 = _6 16; _11 = _10 4294967295; _13 = a$rgba_5 65535; _15 = _13 | 264913582817280; _16 = _8 | _15; _14 = _11 | _16; MEM[(struct MyRgba64 *)D.2451] = _14; return D.2451; Richi, can these shifts be converted to equivalent masking in tree optimizers?
[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351 --- Comment #4 from Andrew Pinski pinskia at gcc dot gnu.org --- (In reply to Uroš Bizjak from comment #3) (In reply to Uroš Bizjak from comment #2) (In reply to Allan Jensen from comment #0) Gcc will expand and detect field setting on 32-bit integers, but for some reason miss the opportunity on 64-bit. The immediates for 64bit logic insns are limited to sign-extended 32bit values, so this probably limits combine to combine several insns into one. One example is: (insn 8 6 9 2 (parallel [ (set (reg:DI 100) (lshiftrt:DI (reg/v:DI 98 [ a ]) (const_int 48 [0x30]))) (clobber (reg:CC 17 flags)) ]) test.cpp:63 538 {*lshrdi3_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) (insn 9 8 10 2 (parallel [ (set (reg:DI 101) (ashift:DI (reg:DI 100) (const_int 48 [0x30]))) (clobber (reg:CC 17 flags)) ]) test.cpp:63 504 {*ashldi3_1} (expr_list:REG_DEAD (reg:DI 100) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil combine tries to: Trying 8 - 9: Failed to match this instruction: (parallel [ (set (reg:DI 101) (and:DI (reg/v:DI 98 [ a ]) (const_int -281474976710656 [0x]))) (clobber (reg:CC 17 flags)) ]) However, tree optimizers pass to expand the following sequence: a = giveMe64 (); a$rgba_5 = MEM[(struct MyRgba64 *)a]; _6 = a$rgba_5 16; _7 = a$rgba_5 48; _8 = _7 48; _10 = _6 16; _11 = _10 4294967295; _13 = a$rgba_5 65535; _15 = _13 | 264913582817280; _16 = _8 | _15; _14 = _11 | _16; MEM[(struct MyRgba64 *)D.2451] = _14; return D.2451; Richi, can these shifts be converted to equivalent masking in tree optimizers? They should be or at least Naveen's patches should handle them. There is an open bug filed doing a N N and one filed for a N N already (I filed it).
[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351 --- Comment #5 from Andrew Pinski pinskia at gcc dot gnu.org --- Oh his patch only handled multiplies/divide and not shifts. But it should be easy to add them to match.pd to simplify this at the tree level.
[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351 --- Comment #2 from Uroš Bizjak ubizjak at gmail dot com --- (In reply to Allan Jensen from comment #0) Gcc will expand and detect field setting on 32-bit integers, but for some reason miss the opportunity on 64-bit. The immediates for 64bit logic insns are limited to sign-extended 32bit values, so this probably limits combine to combine several insns into one.