Differentiating if-then and if-then-else constructs in IR?

Hi all,

I am looking for a way to keep if-then and if-then-else constructs apart in IR.

Say we have the following construct:

if(foo) {
  // More code
  return 42;
}
// More code
return 21;

Assuming that function returns have been unified, we’ll end up with something like this in IR I presume:

if(foo) {
  // More code
  goto end;
}
// More code
goto end;

end:
  // Phi node
  return PhiVal;

This is equivalent to:

if(foo) {
  // More code
  goto end;
} else {
  // More code
  goto end;
}

end:
  PhiVal = [ /* Assign value based on predecessor */ ];
  return PhiVal;

Is there a way to tell where the IR came from, i.e. whether it originated in an if-then or if-then-else construct? Any pointers? Or in other words, can I figure out whether the basic block which is entered when the if condition evaluates to false is part of an else or not?

AFAICT, branch statements don’t differentiate between if-then and if-then-else constructs. The standard way would be to use post-dominance, but that wouldn’t work here as it would treat both cases the same way? (Also it is something I cannot use in my scenario, but that’s another story)

Many thanks,
Paul

Hi Paul,

Disclaimer: I haven’t tried to compile these to IR to give a concrete answer.

Post-dominance analysis would certainly be the way I’d handle it, and yes, it would treat both cases the same. But the question becomes: does it really matter? It treats them the same because the flow logic is the same; the only variation is the source syntax. If you were to compile this down to a binary and run it through a decompiler like Hex-Rays or Ghidra, the pseudo-source with which you’d be presented is going to show it one way or the other and not necessarily match the control flow structure of the original source exactly.

(I’m really not trying to make this sound like a StackOverflow “XY-problem” answer…)

Many thanks for getting back to me!

I figured someone might say that, and of course you’re completely right. I initially thought that it might still matter for my purposes where the code came from, but actually I might be able to get away with treating both cases the same. So, it doesn’t appear to be a problem after all.

I wasn’t aware of those two - thanks!

Paul