Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dead Code Elimination Regression at -O3 (trunk vs 13.0.0) #51885

Closed
llvmbot opened this issue Nov 18, 2021 · 4 comments
Closed

Dead Code Elimination Regression at -O3 (trunk vs 13.0.0) #51885

llvmbot opened this issue Nov 18, 2021 · 4 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 18, 2021

Bugzilla Link 52543
Resolution FIXED
Resolved on Nov 20, 2021 12:39
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @rotateright
Fixed by commit(s) 337948a

Extended Description

cat case.c
void foo(void);

static unsigned char f(int *x) { return *x; }

static int b = -1;

int main() {
unsigned char c = f(&b);
unsigned char r = c >= 2 ? 1 : 1 << c;
if (!r)
foo();
b = 0;
}

trunk cannot eliminate the call to foo but 13.0.0 can:

clang-13.0.0 -O3 -S -o /dev/stdout case.c
main: # @​main
.cfi_startproc

%bb.0:

movb	$1, b(%rip)
xorl	%eax, %eax
retq

.Lfunc_end0:

clang-trunk -O3 -S -o /dev/stdout case.c
main: # @​main
.cfi_startproc

%bb.0:

pushq	%rax
.cfi_def_cfa_offset 16
movb	b(%rip), %al
xorb	$1, %al
movzbl	%al, %ecx
movl	%ecx, %edx
andl	$1, %edx
negl	%edx
andb	$1, %cl
negb	%cl
movl	$1, %eax
                                    # kill: def $cl killed $cl killed $ecx
shll	%cl, %eax
testb	$-2, %dl
jne	.LBB0_3

%bb.1:

testb	%al, %al
jne	.LBB0_3

%bb.2:

callq	foo

.LBB0_3:
movb $1, b(%rip)
xorl %eax, %eax
popq %rcx
.cfi_def_cfa_offset 8
retq
.Lfunc_end0:

clang-trunk -v
clang version 14.0.0 (https://github.com/llvm/llvm-project 693b020)
Target: x86_64-unknown-linux-gnu
Thread model: posix

Started with acabad9

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 18, 2021

assigned to @rotateright

@rotateright
Copy link
Contributor

Started with
https://github.com/llvm/llvm-project/commit/
acabad9

The irony is that patch solved a previous bug similar to this one - bug 52260. :)

We're missing some kind of canonicalization/analysis in instcombine/value tracking.

This case reduces to:
https://alive2.llvm.org/ce/z/qMCISF

define i1 @​src(i1 %b) {
%not..b = xor i1 %b, true
%t0 = sext i1 %not..b to i32
%conv = and i32 %t0, 255
%t1 = and i32 %t0, 254
%cmp = icmp eq i32 %t1, 0
%shl = shl nuw i32 1, %conv
%t2 = trunc i32 %shl to i8
%tobool.not5 = icmp eq i8 %t2, 0
%r = select i1 %cmp, i1 %tobool.not5, i1 false
ret i1 %r
}

define i1 @​tgt(i1 %b) {
ret i1 0
}

@rotateright
Copy link
Contributor

The sequence in comment 1 actually shows multiple failures. Fixing any of them may solve the larger example, so I forked some over to new bug reports for independent tracking.

Extra use prevents converting and-of-sext to select:
https://alive2.llvm.org/ce/z/ZpyTyi

declare void @​use(i32)

define i32 @​src(i1 %b) {
%s = sext i1 %b to i32
call void @​use(i32 %s) ; extra use is preventing an existing fold
%a = and i32 %s, 254
ret i32 %a
}

define i32 @​tgt(i1 %b) {
%s = sext i1 %b to i32
call void @​use(i32 %s)
%r = select i1 %b, i32 254, i32 0
ret i32 %r
}

I'll keep this one here for now. I'm not sure yet if converting to select if the mask is not a constant is worthwhile - that could potentially lead to other problems because that's not reversible:
https://alive2.llvm.org/ce/z/KLS2GM

@rotateright
Copy link
Contributor

Should be fixed with:
https://reviews.llvm.org/rG337948ac6e22

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla
Projects
None yet
Development

No branches or pull requests

2 participants