Skip to content

Missing redundancy elimination for uadd.with.overflow and manual overflow check #40192

@nikic

Description

@nikic
Bugzilla Link 40846
Version trunk
OS All
CC @alex,@comex,@nelhage
Fixed by commit(s) 8db5143

Extended Description

Originally reported at: rust-lang/rust#58692

The following IR remains unchanged under opt -O3:

define i1 @​test(i64 %x, i64 %y) nounwind {
%a = call { i64, i1 } @​llvm.uadd.with.overflow.i64(i64 %x, i64 %y)
%b = extractvalue { i64, i1 } %a, 1
br i1 %b, label %trap, label %bb

bb:
%c = extractvalue { i64, i1 } %a, 0
%d = icmp ult i64 %c, %x
ret i1 %d

trap:
call void @​llvm.trap()
unreachable
}

declare { i64, i1 } @​llvm.uadd.with.overflow.i64(i64, i64)
declare void @​llvm.trap()

Here %d is the same as %b, and must be false in %bb by implication.

I think this should be fairly easy to fix (at least for this specific case) with an instcombine pattern that converts the icmp into an extract, and CSE/GVN will take care of the rest.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions