Skip to content

Missed canonicalizations for losslessness checks of unsigned integer demotions #43445

@LebedevRI

Description

@LebedevRI
Bugzilla Link 44100
Version trunk
OS Linux
CC @annamthomas,@RKSimon,@rotateright,@TNorthover
Fixed by commit(s) 0f22e78

Extended Description

Given

unsigned short t0(unsigned short x) {
x+=1;
return x;
}
unsigned short t1(unsigned short x) {
x-=1;
return x;
}

With -fsanitize=implicit-conversion we produce:

%3 = add nuw nsw i32 %2, 1, !dbg !​15
%4 = trunc i32 %3 to i16, !dbg !​15
%5 = icmp ult i32 %3, 65536, !dbg !​15

and

%2 = zext i16 %0 to i32, !dbg !​22
%3 = add nsw i32 %2, -1, !dbg !​22
%4 = trunc i32 %3 to i16, !dbg !​22
%5 = icmp ult i32 %3, 65536, !dbg !​22

https://godbolt.org/z/Us33sA

But in these cases we can simply check the original %2:

Name: unsigned truncation check - increment
Pre: C2 u>= C1
%add = add nuw i32 %conv, C1 ; has extra uses
%cmp = icmp ult i32 %add, C2 ; is truncation NUW?
=>
%cmp = icmp ult i32 %conv, (C2-C1)

Name: unsigned truncation check - decrement
Pre: C1 <= 0 ; C1 is non-positive
%conv = zext i16 %x to i32
%add = add i32 %conv, C1 ; has extra uses
%cmp = icmp ult i32 %add, 65536 ; is truncation NUW?
=>
%cmp = icmp uge i32 %conv, -C1

https://rise4fun.com/Alive/x35G

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzilla

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions