http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59880
Bug ID: 59880 Summary: Improve REE for implicit SI->DI zero-extend Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: hjl.tools at gmail dot com After r206774, on Linux/x86-64, the following code ---foo.c--- extern __thread unsigned int __bid_IDEC_glbflags; typedef unsigned long long UINT64; typedef __attribute__ ((aligned(16))) struct { UINT64 w[2]; } UINT128; extern UINT64 __bid64_from_uint64 (UINT64); extern void __bid_round64_2_18 (int q, int x, UINT64 C, UINT64 * ptr_Cstar, int *delta_exp, int *ptr_is_midpoint_lt_even, int *ptr_is_midpoint_gt_even, int *ptr_is_inexact_lt_midpoint, int *ptr_is_inexact_gt_midpoint); extern void __bid_round128_19_38 (int q, int x, UINT128 C, UINT128 * ptr_Cstar, int *delta_exp, int *ptr_is_midpoint_lt_even, int *ptr_is_midpoint_gt_even, int *ptr_is_inexact_lt_midpoint, int *ptr_is_inexact_gt_midpoint); UINT64 __bid64_from_uint64 (UINT64 x) { UINT64 res; UINT128 x128, res128; unsigned int q, ind; int incr_exp = 0; int is_midpoint_lt_even = 0, is_midpoint_gt_even = 0; int is_inexact_lt_midpoint = 0, is_inexact_gt_midpoint = 0; if (x <= 0x002386F26FC0ffffull) { if (x < 0x0020000000000000ull) { res = 0x31c0000000000000ull | x; } else { res = 0x6c70000000000000ull | (x & 0x0007ffffffffffffull); } } else { if (x < 0x16345785d8a0000ull) { q = 17; ind = 1; } else if (x < 0xde0b6b3a7640000ull) { q = 18; ind = 2; } else if (x < 0x8ac7230489e80000ull) { q = 19; ind = 3; } else { q = 20; ind = 4; } if (q <= 19) { __bid_round64_2_18 ( q, ind, x, &res, &incr_exp, &is_midpoint_lt_even, &is_midpoint_gt_even, &is_inexact_lt_midpoint, &is_inexact_gt_midpoint); } else { x128.w[1] = 0x0; x128.w[0] = x; __bid_round128_19_38 (q, ind, x128, &res128, &incr_exp, &is_midpoint_lt_even, &is_midpoint_gt_even, &is_inexact_lt_midpoint, &is_inexact_gt_midpoint); res = res128.w[0]; } if (incr_exp) ind++; if (is_inexact_lt_midpoint || is_inexact_gt_midpoint || is_midpoint_lt_even || is_midpoint_gt_even) *&__bid_IDEC_glbflags |= 0x00000020; if (res < 0x0020000000000000ull) { res = (((UINT64) ind + 398) << 53) | res; } else { res = 0x6000000000000000ull | (((UINT64) ind + 398) << 51) | (res & 0x0007ffffffffffffull); } } return(res);; } ----------- contains 2 extra SI->DI zero-extend when compiled with -O2 -march=corei7 -mtune=slm -fPIC movl %ebp, %edx # 311 *movsi_internal/1 [length = 2] ^^^^^^^^^^^^^^^^^^^ Implicit SI->DI zero-extend leaq 88(%rsp), %rsp # 267 pro_epilogue_adjust_stack_di_add/1 [length = 5] .cfi_remember_state .cfi_def_cfa_offset 24 movabsq $2251799813685247, %rax # 101 *movdi_internal/5 [length = 10] movl %edx, %edx # 312 *zero_extendsidi2/4 [length = 2] ^^^^^^^^^^^^^^^^^^^ Unnecessary movl %ebp, %eax # 308 *movsi_internal/1 [length = 2] ^^^^^^^^^^^^^^^^^^^ Implicit SI->DI zero-extend leaq 88(%rsp), %rsp # 287 pro_epilogue_adjust_stack_di_add/1 [length = 5] .cfi_remember_state .cfi_def_cfa_offset 24 movl %eax, %eax # 309 *zero_extendsidi2/4 [length = 2] ^^^^^^^^^^^^^^^^^^^^ Unnecessary REE pass should remove them.