[cfe-dev] the "computed goto" problem
De Azevedo Piovezan, Felipe via cfe-dev
cfe-dev at lists.llvm.org
Thu Oct 3 05:48:15 PDT 2019
Hello cfe,
This year at CppCon (https://www.youtube.com/watch?v=9cPU1NdsgDQ), there was a funny talk about the use of what they called a "computed goto".
I was playing around with the idea, and there might be something incorrect about the code generated by clang when constexpr is involved (starting with 9.0).
The idea is this: the address of a bunch of labels are taken and stored into a table:
enum bytecode : int8_t { add1, add2, halt };
constexpr void* labels[] = {
[bytecode::add1] = &&add1_label,
[bytecode::add2] = &&add2_label,
[bytecode::halt] = &&halt_label,
};
//labels defined here...
However, this is the IR generated with -O0 -emit-llvm:
@labels = private unnamed_addr constant [3 x i8*] [i8* blockaddress(@"label1", <badref>), i8* blockaddress(@"label2", <badref>), i8* blockaddress(@"label3", <badref>)], align 16
Note the badrefs! Also, we generate a basic block with no predecessors:
12: ; No predecessors!
indirectbr i8* undef, [label <badref>, label <badref>, label <badref>]
As such, as soon as we start optimizing, the whole function is optimized away.
If we remove constexpr, however, everything seems sane. Godbolt link: https://godbolt.org/z/Anc9EI
Any insights on what might be happening here? I suspect a lot of people will play around with this construction just "for fun" and will encounter this.
--
Felipe
More information about the cfe-dev
mailing list