Skip to content

__builtin_assume pessimization #25850

@llvmbot

Description

@llvmbot
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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions