-
Couldn't load subscription status.
- Fork 15k
Closed
Labels
Description
| Bugzilla Link | 25476 |
| Version | 3.7 |
| OS | Linux |
| Reporter | LLVM Bugzilla Contributor |
| CC | @davidstone,@hfinkel |
Extended Description
Consider the code: [c.f. https://goo.gl/7VB27y ]
enum class Side { Bid, Ask };
struct Foo { int a; int b; };
int test(Side side, const Foo &foo) {
if (side == Side::Bid) return foo.a;
return foo.b;
}
int test_with_unreachable(Side side, const Foo &foo) {
if (side == Side::Bid) return foo.a;
if (side == Side::Ask) return foo.b;
__builtin_unreachable();
}
int test_with_assume(Side side, const Foo &foo) {
__builtin_assume(side == Side::Bid || side == Side::Ask);
if (side == Side::Bid) return foo.a;
return foo.b;
}
int test_with_assume2(Side side, const Foo &foo) {
if (side == Side::Bid) return foo.a;
__builtin_assume(side == Side::Ask);
return foo.b;
}
One might expect the generated code to basically be the same, but the _assume2 case generates a branch instead of the conditional moves emitted elsewhere.
e.g.
test(Side, Foo const&): # @​test(Side, Foo const&)
lea rax, [rsi + 4]
test edi, edi
cmove rax, rsi
mov eax, dword ptr [rax]
ret
vs
test_with_assume2(Side, Foo const&): # @​test_with_assume2(Side, Foo const&)
test edi, edi
je .LBB3_2
add rsi, 4
.LBB3_2:
mov eax, dword ptr [rsi]
ret
This would appear to be a pessimization.
Arguably given the __builtin_assumption that the Side is either 0 or 1, one might hope the following code could be generated:
mov eax, dword ptr [rsi+edx*4]
ret
GCC has a similar bug with __builtin_unreachable (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68274)