Skip to content

Dead Code Elimination Regression at -O2 (trunk vs. 13.0.0) #53320

@Quarub

Description

@Quarub

cat case.c #5986
case.txt

struct {
  signed b;
  char c;
  unsigned : 9;
  unsigned d : 1;
  signed k: 7;
} e;
void foo(void);
long(a)(long f, long g) { return f > 9223372036854775807 - g ? f : g; }
int main() {
  a(0, 0);
  if (e.d)
    e.b = 0;
  if (!a(2, e.c ^ 128))
    foo();
}

clang-f29256a64ac11cf59cea878c8d1ba9537db4f523 (trunk) -O2 can not eliminate foo but clang-llvmorg-13.0.0 -O2 can.

Target: x86_64-unknown-linux-gnu


clang-f29256a64ac11cf59cea878c8d1ba9537db4f523 (trunk) -O2 [-emit-llvm] -S -o /dev/stdout case.c

Emitted IR

; ModuleID = 'case.c'
source_filename = "case.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.anon = type { i32, i8, [3 x i8] }

@e = dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4

; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn
define dso_local i64 @a(i64 noundef %0, i64 noundef %1) local_unnamed_addr #0 {
  %3 = sub nsw i64 9223372036854775807, %1
  %4 = icmp slt i64 %3, %0
  %5 = select i1 %4, i64 %0, i64 %1
  ret i64 %5
}

; Function Attrs: nounwind uwtable
define dso_local i32 @main() local_unnamed_addr #1 {
  %1 = load i24, i24* bitcast ([3 x i8]* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 2) to i24*), align 1
  %2 = and i24 %1, 512
  %3 = icmp eq i24 %2, 0
  br i1 %3, label %5, label %4

4:                                                ; preds = %0
  store i32 0, i32* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 0), align 4, !tbaa !3
  br label %5

5:                                                ; preds = %4, %0
  %6 = load i8, i8* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 1), align 4, !tbaa !8
  %7 = sext i8 %6 to i64
  %8 = xor i64 %7, 128
  %9 = and i64 %8, -2
  %10 = icmp ne i64 %9, 9223372036854775806
  %11 = icmp eq i64 %8, 0
  %12 = and i1 %11, %10
  br i1 %12, label %13, label %14

13:                                               ; preds = %5
  tail call void @foo() #3
  br label %14

14:                                               ; preds = %13, %5
  ret i32 0
}

declare dso_local void @foo() local_unnamed_addr #2

attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #2 = { "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #3 = { nounwind }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"uwtable", i32 1}
!2 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git f29256a64ac11cf59cea878c8d1ba9537db4f523)"}
!3 = !{!4, !5, i64 0}
!4 = !{!"", !5, i64 0, !6, i64 4, !5, i64 6, !5, i64 6}
!5 = !{!"int", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
!7 = !{!"Simple C/C++ TBAA"}
!8 = !{!4, !6, i64 4}

Reduced assembly

main:                                   # @main
	.cfi_startproc
# %bb.0:
	pushq	%rax
	.cfi_def_cfa_offset 16
	movzwl	e+5(%rip), %eax
	testl	$512, %eax                      # imm = 0x200
	je	.LBB1_2
# %bb.1:
	movl	$0, e(%rip)
.LBB1_2:
	movsbq	e+4(%rip), %rax
	xorq	$128, %rax
	jne	.LBB1_5
# %bb.3:
	andq	$-2, %rax
	movabsq	$9223372036854775806, %rcx      # imm = 0x7FFFFFFFFFFFFFFE
	cmpq	%rcx, %rax
	je	.LBB1_5
# %bb.4:
	callq	foo
.LBB1_5:
	xorl	%eax, %eax
	popq	%rcx
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end1:
	.size	main, .Lfunc_end1-main


clang-llvmorg-13.0.0 -O2 [-emit-llvm] -S -o /dev/stdout case.c

Emitted IR

; ModuleID = 'case.c'
source_filename = "case.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.anon = type { i32, i8, [3 x i8] }

@e = dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4

; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn
define dso_local i64 @a(i64 %0, i64 %1) local_unnamed_addr #0 {
  %3 = sub nsw i64 9223372036854775807, %1
  %4 = icmp slt i64 %3, %0
  %5 = select i1 %4, i64 %0, i64 %1
  ret i64 %5
}

; Function Attrs: nounwind uwtable
define dso_local i32 @main() local_unnamed_addr #1 {
  %1 = load i24, i24* bitcast ([3 x i8]* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 2) to i24*), align 1
  %2 = and i24 %1, 512
  %3 = icmp eq i24 %2, 0
  br i1 %3, label %5, label %4

4:                                                ; preds = %0
  store i32 0, i32* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 0), align 4, !tbaa !3
  br label %5

5:                                                ; preds = %0, %4
  ret i32 0
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"uwtable", i32 1}
!2 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git d7b669b3a30345cfcdb2fde2af6f48aa4b94845d)"}
!3 = !{!4, !5, i64 0}
!4 = !{!"", !5, i64 0, !6, i64 4, !5, i64 6, !5, i64 6}
!5 = !{!"int", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
!7 = !{!"Simple C/C++ TBAA"}

Reduced assembly

main:                                   # @main
	.cfi_startproc
# %bb.0:
	movzwl	e+5(%rip), %eax
	testl	$512, %eax                      # imm = 0x200
	je	.LBB1_2
# %bb.1:
	movl	$0, e(%rip)
.LBB1_2:
	xorl	%eax, %eax
	retq
.Lfunc_end1:
	.size	main, .Lfunc_end1-main


Bisection

Bisected to: b554e41
Committed by: @LebedevRI


clang-b554e41e2d15b78679231b390e543153e05c9efe -O2 [-emit-llvm] -S -o /dev/stdout case.c

Emitted IR

; ModuleID = 'case.c'
source_filename = "case.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.anon = type { i32, i8, [3 x i8] }

@e = dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4

; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn
define dso_local i64 @a(i64 %0, i64 %1) local_unnamed_addr #0 {
  %3 = sub nsw i64 9223372036854775807, %1
  %4 = icmp slt i64 %3, %0
  %5 = select i1 %4, i64 %0, i64 %1
  ret i64 %5
}

; Function Attrs: nounwind uwtable
define dso_local i32 @main() local_unnamed_addr #1 {
  %1 = load i24, i24* bitcast ([3 x i8]* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 2) to i24*), align 1
  %2 = and i24 %1, 512
  %3 = icmp eq i24 %2, 0
  br i1 %3, label %5, label %4

4:                                                ; preds = %0
  store i32 0, i32* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 0), align 4, !tbaa !3
  br label %5

5:                                                ; preds = %4, %0
  %6 = load i8, i8* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 1), align 4, !tbaa !8
  %7 = sext i8 %6 to i64
  %8 = xor i64 %7, 128
  %9 = and i64 %8, -2
  %10 = icmp ne i64 %9, 9223372036854775806
  %11 = icmp eq i64 %8, 0
  %12 = and i1 %11, %10
  br i1 %12, label %13, label %14

13:                                               ; preds = %5
  tail call void @foo() #3
  br label %14

14:                                               ; preds = %13, %5
  ret i32 0
}

declare dso_local void @foo() local_unnamed_addr #2

attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #2 = { "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #3 = { nounwind }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"uwtable", i32 1}
!2 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git b554e41e2d15b78679231b390e543153e05c9efe)"}
!3 = !{!4, !5, i64 0}
!4 = !{!"", !5, i64 0, !6, i64 4, !5, i64 6, !5, i64 6}
!5 = !{!"int", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
!7 = !{!"Simple C/C++ TBAA"}
!8 = !{!4, !6, i64 4}

Reduced assembly

main:                                   # @main
	.cfi_startproc
# %bb.0:
	pushq	%rax
	.cfi_def_cfa_offset 16
	movzwl	e+5(%rip), %eax
	testl	$512, %eax                      # imm = 0x200
	je	.LBB1_2
# %bb.1:
	movl	$0, e(%rip)
.LBB1_2:
	movsbq	e+4(%rip), %rax
	xorq	$128, %rax
	jne	.LBB1_5
# %bb.3:
	andq	$-2, %rax
	movabsq	$9223372036854775806, %rcx      # imm = 0x7FFFFFFFFFFFFFFE
	cmpq	%rcx, %rax
	je	.LBB1_5
# %bb.4:
	callq	foo
.LBB1_5:
	xorl	%eax, %eax
	popq	%rcx
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end1:
	.size	main, .Lfunc_end1-main


Previous commit: 81441cf

clang-81441cf44c145e1d90a10c743e0190a44fbf8fcb -O2 [-emit-llvm] -S -o /dev/stdout case.c

Emitted IR

; ModuleID = 'case.c'
source_filename = "case.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.anon = type { i32, i8, [3 x i8] }

@e = dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4

; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn
define dso_local i64 @a(i64 %0, i64 %1) local_unnamed_addr #0 {
  %3 = sub nsw i64 9223372036854775807, %1
  %4 = icmp slt i64 %3, %0
  %5 = select i1 %4, i64 %0, i64 %1
  ret i64 %5
}

; Function Attrs: nounwind uwtable
define dso_local i32 @main() local_unnamed_addr #1 {
  %1 = load i24, i24* bitcast ([3 x i8]* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 2) to i24*), align 1
  %2 = and i24 %1, 512
  %3 = icmp eq i24 %2, 0
  br i1 %3, label %5, label %4

4:                                                ; preds = %0
  store i32 0, i32* getelementptr inbounds (%struct.anon, %struct.anon* @e, i64 0, i32 0), align 4, !tbaa !3
  br label %5

5:                                                ; preds = %0, %4
  ret i32 0
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"uwtable", i32 1}
!2 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git 81441cf44c145e1d90a10c743e0190a44fbf8fcb)"}
!3 = !{!4, !5, i64 0}
!4 = !{!"", !5, i64 0, !6, i64 4, !5, i64 6, !5, i64 6}
!5 = !{!"int", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
!7 = !{!"Simple C/C++ TBAA"}

Reduced assembly

main:                                   # @main
	.cfi_startproc
# %bb.0:
	movzwl	e+5(%rip), %eax
	testl	$512, %eax                      # imm = 0x200
	je	.LBB1_2
# %bb.1:
	movl	$0, e(%rip)
.LBB1_2:
	xorl	%eax, %eax
	retq
.Lfunc_end1:
	.size	main, .Lfunc_end1-main

Edit: Added IR

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions