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

SimplifyCFGPass incorrectly hoists load before loop that can have zero iterations #92274

Closed
GoldsteinE opened this issue May 15, 2024 · 2 comments

Comments

@GoldsteinE
Copy link

C++ reproducer:

int ub(int &foo, int count) {
  delete &foo;
  int x = {};
  for (int i = 0; i < count; i++)
    x += foo;
  return x;
}

This code compiles to

define dso_local noundef i32 @ub(int&, int)(ptr noundef nonnull align 4 dereferenceable(4) %foo, i32 noundef %count) local_unnamed_addr {
entry:
  tail call void @operator delete(void*)(ptr noundef nonnull %foo) #3
  %cmp4 = icmp sgt i32 %count, 0
  %0 = load i32, ptr %foo, align 4
  ; ^ unconditional UB: load from a dead pointer
  %1 = mul i32 %0, %count
  %x.0.lcssa = select i1 %cmp4, i32 %1, i32 0
  ret i32 %x.0.lcssa
}

turning conditional UB (on count != 0) into an unconditional one.

This is flagged as incorrect by alive2: https://alive2.llvm.org/ce/z/c3KXo9

Originaly discovered by @feedab1e

@GoldsteinE
Copy link
Author

Looking at godbolt’s “Opt Pipeline”, it looks like this SimplifyCFGPass causes the problem:

 define dso_local noundef i32 @ub(int&, int)(ptr noundef nonnull align 4 dereferenceable(4) %foo, i32 noundef %count) local_unnamed_addr {
 entry:
     #dbg_value(ptr %foo, !17, !DIExpression(), !22)
     #dbg_value(i32 %count, !18, !DIExpression(), !22)
   tail call void @operator delete(void*)(ptr noundef nonnull %foo)
     #dbg_value(i32 0, !19, !DIExpression(), !22)
     #dbg_value(i32 0, !20, !DIExpression(), !24)
   %cmp4 = icmp sgt i32 %count, 0
-  br i1 %cmp4, label %for.body.lr.ph, label %for.cond.cleanup
-
-for.body.lr.ph:                                   ; preds = %entry
   %0 = load i32, ptr %foo, align 4
-    #dbg_value(i32 poison, !20, !DIExpression(), !24)
-    #dbg_value(i32 poison, !19, !DIExpression(), !22)
   %1 = mul i32 %0, %count
-  br label %for.cond.cleanup
-
-for.cond.cleanup:                                 ; preds = %for.body.lr.ph, %entry
-  %x.0.lcssa = phi i32 [ 0, %entry ], [ %1, %for.body.lr.ph ]
+  %x.0.lcssa = select i1 %cmp4, i32 %1, i32 0
   ret i32 %x.0.lcssa
 }

@efriedma-quic
Copy link
Collaborator

Duplicate of #37011 .

@efriedma-quic efriedma-quic closed this as not planned Won't fix, can't repro, duplicate, stale May 15, 2024
@EugeneZelenko EugeneZelenko added the duplicate Resolved as duplicate label May 15, 2024
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

4 participants