On Sat, Jul 19, 2025 at 8:41 PM ywgrit via Gcc <gcc@gcc.gnu.org> wrote: > > I've tested merging for nested branches on icc, and it seems that icc does > a branch merge for code that might trap, making a more aggressive > optimization.
So it is not exactly it might trap but rather it is part of a bigger struct and it is an adjacent location. We do some of this already in phiopt see hoist_adjacent_loads in tree-ssa-phiopt.cc which handles a similar but different case. Added here originally (https://inbox.sourceware.org/gcc-patches/1336055636.22269.16.camel@gnopaine/). Seems like a similar code could be done for ifcombine. I thought I saw some improvements dealing with load handling that happened for GCC 15. Thanks, Andrew > Way_.cpp > struct waymapt > { > int fillnum; > int num; > }; > typedef waymapt* waymappt; > > class wayobj > { > public: > int boundl; > waymappt waymap; int makebound2(int fillnum, int iters); > }; > > int wayobj::makebound2(int fillnum, int iters) > { > for (int i = 0; i < iters; i++) > { > if (waymap[i].fillnum!=fillnum) > if (waymap[i].num!=0) > boundl++; > } > return boundl; > } > > compile commandline > icpc -c -o Way_.o -g -O3 Way_.cpp > > The instructions generated > cmp (%r11,%r9,1),%esi > setne %bpl > xor %ecx,%ecx > cmpl $0x0,0x4(%r11,%r9,1) > setne %cl > and %ecx,%ebp > cmp $0x1,%ebp > jne 49 <_ZN6wayobj10makebound2Eii+0x49> > > ywgrit <yw987194...@gmail.com> 于2025年7月20日周日 11:11写道: > > > Can we add a -merge-branch option to merge branch bbs when the programmer > > can ensure that the inner branch bb will not trap? > > Also, the current ifcombine pass can only merge very simple nested > > branches, and if statements usually generate multiple gimple statements, so > > a lot of merge opportunities are lost. For example, the hotspot function in > > speccpu 2006's 473.astar program contains two nested branches, we did an > > experiment with the environment:gcc-12.3.0, linux 5.15.0, intel core > > i7-10750h, and after the experiment, compared to generating two branch > > instructions, if the nested branches of the hotspot function are compiled > > into one branch instruction. There will be a 30% improvement in performance. > > If there are indirect accesses in the if statement, the branch prediction > > is probably not accurate, so I think it's important to maximize the chances > > of merging as much as possible, e.g. by adding a -merge-branch option as > > described above. > > > > Richard Biener <rguent...@suse.de> 于2025年7月18日周五 22:37写道: > > > >> On Fri, 18 Jul 2025, ywgrit wrote: > >> > >> > For now, if combine pass can combine the simple nested comparison > >> branches, > >> > e.g. > >> > if (a != b) > >> > if (c == d) > >> > These cond bbs must have only the conditional, which is too harsh. > >> > > >> > We often meet code like this: > >> > if (a != b) > >> > if (m[index] == k[index]) > >> > m and c are arrays, so the 2nd branch belongs to a bb that has mem_ref > >> > gimples and these stmts could trap. So these stmts won't pass the > >> > bb_no_side_effects_p check, the branches can't be merged and performance > >> > gains are lost, what are the way to merge these branches bb? > >> > I think there are extremely many such nested branches and probably the > >> > prediction accuracy of such nested branches is not very high, so doing > >> > branch merging will result in high performance gain. > >> > >> Without actual data I do not believe such general claim. But the issue > >> is that we cannot speculate the loads from m[index] or k[index] when > >> they might trap, so there is no way to merge the branches. > >> > >> Intel APX introduces conditional moves that hide traps, so with that > >> you could do > >> > >> flag = a != b; > >> cmov<flag> m[index], reg1 > >> cmov<flag> k[index], reg2 > >> if (flag && reg1 == reg2) > >> > >> but there is no way to do this in ifcombine on GIMPLE. It would > >> also be slower in case if (a != b) is well predicted and mostly > >> false. > >> > >> Richard. > >> > >