Semantics of Cmm `switch` statement?
Norman Ramsey
nr at cs.tufts.edu
Wed Jan 12 00:02:29 UTC 2022
For testing purposes, I created the following Cmm program:
myswitch (bits32 n) {
switch [0 .. 4] n {
case 0, 1: { foreign "C" A(); }
case 2: { foreign "C" B(); }
case 4: { foreign "C" C(); }
default: { foreign "C" D(); }
}
return (666);
}
In the original C-- specification, it's pretty clear that when, say,
the call to foreign function `A` terminates, the switch statement is
supposed to finish and function `myswitch` is supposed to return 666.
What actually happens in GHC is that this source code is parsed into a
control-flow graph in which execution loops forever, repeating the
call. The relevant fragment of the prettyprinted CFG looks like this:
{offset
ca: // global
_c1::I32 = %MO_XX_Conv_W64_W32(R1);
//tick src<programs/panic.cmm:(1,21)-(9,1)>
switch [0 .. 4] _c1::I32 {
case 0, 1 : goto c5;
case 2 : goto c7;
case 4 : goto c9;
default: {goto c3;}
}
...
c5: // global
//tick src<programs/panic.cmm:3:16-35>
_c4::I64 = A;
call "ccall" arg hints: [] result hints: [] (_c4::I64)();
goto c5;
...
}
Surprising, at least to me.
Is this behavior a bug or a feature? And if it is a feature, can
anyone explain it to me?
Norman
More information about the ghc-devs
mailing list