Skip to content

[missed optimization] Missed removing loop of setting zero when dereference pointer (memset) #139810

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

Open
BreadTom opened this issue May 13, 2025 · 1 comment

Comments

@BreadTom
Copy link

Godbolt and GCC Bug

void f0(unsigned char *ptr, unsigned long len){
    for(unsigned long i = 0; i < len; ++i){
        ptr[i] = 0;
    }
}

void f1(unsigned char *ptr, unsigned long len){
    for(unsigned long i = 0; i < len; ++i){
        while(ptr[i])
            ptr[i]--;
    }
}

void f2(unsigned char *ptr){
    while(ptr[0])
        ptr[0]--;
}

When flags are -O3,
f1() compares if ptr[i] is zero before setting it to zero and f0() memset it to zero.

When flags are -O3 and -march=icelake-client, f1() doesn't call memset like f0().

@BreadTom
Copy link
Author

Reduced godbolt code

void f3(unsigned char *ptr){
    if(ptr[0])
        ptr[0] = 0;
}
define dso_local void @f3(ptr noundef captures(none) %ptr) local_unnamed_addr {
entry:
  %0 = load i8, ptr %ptr, align 1
  %tobool.not = icmp eq i8 %0, 0
  br i1 %tobool.not, label %if.end, label %if.then

if.then:
  store i8 0, ptr %ptr, align 1
  br label %if.end

if.end:
  ret void
}

Just like GCC, LLVM does not have a pass for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants