Skip to content

Missed CSE of div+rem #12790

@d0k

Description

@d0k
Bugzilla Link 12418
Version trunk
OS All
CC @lattner,@stoklund

Extended Description

For this test case

void foo(void);

void test(unsigned int x, unsigned int y, unsigned int q, unsigned int r) {
  if ((x / y) != q || (x % y) != r)
    foo();
}

The x86-64 asm generated by clang -O3 looks like this:

_test:                                  ## @test
	.cfi_startproc
## BB#0:                                ## %entry
	movl	%edx, %r8d
	movl	%edi, %eax
	xorl	%edx, %edx
	divl	%esi
	cmpl	%r8d, %eax
	jne	LBB0_3
## BB#1:                                ## %lor.lhs.false
	movl	%edi, %eax
	xorl	%edx, %edx
	divl	%esi
	cmpl	%ecx, %edx
	jne	LBB0_3
## BB#2:                                ## %if.end
	ret
LBB0_3:                                 ## %if.then
	jmp	_foo                    ## TAILCALL

There should be only one "divl" as it can compute div and rem in one go. On ARM we generate a call to __udivsi3 and to __umodsi3, not sure if there is a libcall that handles both but if there is it would be twice as fast.

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