Help with clz(0) and optimization
I am working on GCC for a target architecture where clz(0) is defined and is 32 (TriCore). The code under test is the following: #include int f(unsigned int a) { unsigned int res = 32 - __builtin_clz(a); if(res > 0) printf("test"); return res; } >From GCC version greater and equal to 11, the Tree SSA optimization discards the if condition completely, and always executes the printf. This is the optimized gimplified code at the end of the optimization for GCC12: int f (unsigned int a) { int _1; int _2; [local count: 1073741824]: _1 = __builtin_clz (a_4(D)); _2 = 32 - _1; __printf_chk (1, "test"); return _2; } where GCC10 produces: f (unsigned int a) { int _1; int _2; [local count: 1073741824]: _1 = __builtin_clz (a_4(D)); _2 = 32 - _1; if (_2 != 0) goto ; [33.00%] else goto ; [67.00%] [local count: 354334800]: __printf_chk (1, "test"); [local count: 1073741824]: return _2; } I tried to rebuild defining CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 2) but this doesn't seem to have any effect. I am stuck and need counseling. Can anyone suggest me the next steps? Thank you. Kind regards Enrico Bragante
Re: Help with clz(0) and optimization
On 10/31/23 08:26, Enrico via Gcc wrote: I am working on GCC for a target architecture where clz(0) is defined and is 32 (TriCore). The code under test is the following: #include int f(unsigned int a) { unsigned int res = 32 - __builtin_clz(a); if(res > 0) printf("test"); return res; } From GCC version greater and equal to 11, the Tree SSA optimization discards the if condition completely, and always executes the printf. This is the optimized gimplified code at the end of the optimization for GCC12: int f (unsigned int a) { int _1; int _2; [local count: 1073741824]: _1 = __builtin_clz (a_4(D)); _2 = 32 - _1; __printf_chk (1, "test"); return _2; } where GCC10 produces: f (unsigned int a) { int _1; int _2; [local count: 1073741824]: _1 = __builtin_clz (a_4(D)); _2 = 32 - _1; if (_2 != 0) goto ; [33.00%] else goto ; [67.00%] [local count: 354334800]: __printf_chk (1, "test"); [local count: 1073741824]: return _2; } I tried to rebuild defining CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 2) but this doesn't seem to have any effect. I would look to see the first pass where the condition gets removed using -fdump-tree-all-details. That should give you strong hints about what to look at next. Conceptually something has determined that _2 never has the value 0 which through backwards propagation would indicate that __builtin_clz never returns the value 32. Jeff
Subreg promotion not happening for the test case
Hi Jeff, Robin, This morning I was talking about the following test where subreg promoted is not being generated during expand, whereas for RISC-V ABI/ISA it should. gcc.c-torture/compile/20070121.c -Os -march=rv64gc -mabi=lp64d expand_gimple_basic_block expand_gimple_stmt ... expand_expr_real ... case SSA_NAME: if (REG_P (decl_rtl) && dmode != BLKmode && GET_MODE (decl_rtl) != dmode) Here it seems to be taking promote_ssa_mode () codepath and not promote_function_mode Do note this only happens for -Os. Tree dump is same for both -Os and -O2, Expand for -Os misses setting the subreg promoted. Thx, -Vineet