I have the following question: // Way.h struct waymapt { int fillnum; int num; }; typedef waymapt* waymappt;
class wayobj { public: int bound; int *maparp; waymappt waymap; int makebound2(int fillnum, int iters); void create(int size); }; // WayInit.cpp #include <cstring> #include "Way.h" void wayobj::create(int size) { maparp=new int[size]; waymap=new waymapt[size]; } // Way.cpp #include "Way.h" int wayobj::makebound2(int fillnum, int iters) { for (int i = 0; i < iters; i++) { if (waymap[i].fillnum!=fillnum) if (maparp[i]!=0) bound++; } return bound; } // main.cpp #include <cstdio> #include "Way.h" #define SIZE 16 int main() { wayobj *woj = new wayobj; woj->create(SIZE); woj->makebound2(10, SIZE); printf("bound == %d\n", woj->bound); return 0; } Both maparp and waymap of wayobj are arrays, and in the function wayobj::create, the same number of elements are allocated for both arrays. In function makebound2, if (maparp[i]! = 0) is within if (waymap[i].fillnum!=fillnum). So if "if (waymap[i].fillnum!=fillnum)" won't trap, then "if (maparp[i]! = 0)" won't trap either. Is there a way we can tell that the inner branch won't trap by the relationship between the outer branch and the inner branch? If this is possible then ifcombine pass can do a merge on this nested branch. In spec2006's 473.astar program, this nested branch is a hotspot with poor prediction accuracy, so the performance improvement after merging this nested branches is very significant. Icc merges this nested branch, but gcc doesn't. We modified the following source code in spec2006.473.astar if (waymap[i].fillnum!=fillnum) if (maparp[i]!=0) into a = (waymap[index1].fillnum == fillnum) | maparp[index1] ; if(!a) After the modification, gcc was able to merge the two branches, and we can see from the generated assembly that there is only one jmp instruction There is significant change in the number of branch-misses: gcc-not-combine: 1.5483E+10 gcc-combine: 8.4778E+9