llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.76k stars 10.96k forks source link

trunc nuw x to i1 as branch/select cond implies x #96765

Open sftlbcn opened 1 week ago

sftlbcn commented 1 week ago

https://alive2.llvm.org/ce/z/grTNkc

----------------------------------------
define i32 @src(i32 %x, i32 %y) {
#0:
  %trunc = trunc nuw i32 %x to i1
  %ret = select i1 %trunc, i32 %x, i32 %y
  ret i32 %ret
}
=>
define i32 @tgt(i32 %x, i32 %y) {
#0:
  %trunc = trunc nuw i32 %x to i1
  %ret = select i1 %trunc, i32 1, i32 %y
  ret i32 %ret
}
Transformation seems to be correct!

----------------------------------------
declare void @f()

define i32 @src2(i32 %x, i32 %y) {
bb1:
  %cond = trunc nuw i32 %x to i1
  br i1 %cond, label %bb2, label %bb3

bb2:
  call void @f()
  br label %bb3

bb3:
  %ret = phi i32 [ %y, %bb2 ], [ %x, %bb1 ]
  ret i32 %ret
}
=>
declare void @f()

define i32 @tgt2(i32 %x, i32 %y) {
bb1:
  %cond = trunc nuw i32 %x to i1
  br i1 %cond, label %bb2, label %bb3

bb2:
  call void @f()
  br label %bb3

bb3:
  %ret = phi i32 [ %y, %bb2 ], [ 0, %bb1 ]
  ret i32 %ret
}
Transformation seems to be correct!

Summary:
  2 correct transformations
  0 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors
v01dXYZ commented 1 week ago

This missed optimisation is related to the semantics of nuw/nsw with trunc:

If the nuw keyword is present, and any of the truncated bits are non-zero, the result is a poison value. If the nsw keyword is present, and any of the truncated bits are not the same as the top bit of the truncation result, the result is a poison value.

Essentially your code assume %x can be only 0 or 1.

dtcxzyw commented 4 days ago

Confirmed that this pattern exists in some real-world code :)

llvmbot commented 4 days ago

Hi!

This issue may be a good introductory issue for people new to working on LLVM. If you would like to work on this issue, your first steps are:

  1. Check that no other contributor has already been assigned to this issue. If you believe that no one is actually working on it despite an assignment, ping the person. After one week without a response, the assignee may be changed.
  2. In the comments of this issue, request for it to be assigned to you, or just create a pull request after following the steps below. Mention this issue in the description of the pull request.
  3. Fix the issue locally.
  4. Run the test suite locally. Remember that the subdirectories under test/ create fine-grained testing targets, so you can e.g. use make check-clang-ast to only run Clang's AST tests.
  5. Create a Git commit.
  6. Run git clang-format HEAD~1 to format your changes.
  7. Open a pull request to the upstream repository on GitHub. Detailed instructions can be found in GitHub's documentation. Mention this issue in the description of the pull request.

If you have any further questions about this issue, don't hesitate to ask via a comment in the thread below.

llvmbot commented 4 days ago

@llvm/issue-subscribers-good-first-issue

Author: None (sftlbcn)

https://alive2.llvm.org/ce/z/grTNkc ``` ---------------------------------------- define i32 @src(i32 %x, i32 %y) { #0: %trunc = trunc nuw i32 %x to i1 %ret = select i1 %trunc, i32 %x, i32 %y ret i32 %ret } => define i32 @tgt(i32 %x, i32 %y) { #0: %trunc = trunc nuw i32 %x to i1 %ret = select i1 %trunc, i32 1, i32 %y ret i32 %ret } Transformation seems to be correct! ``` ``` ---------------------------------------- declare void @f() define i32 @src2(i32 %x, i32 %y) { bb1: %cond = trunc nuw i32 %x to i1 br i1 %cond, label %bb2, label %bb3 bb2: call void @f() br label %bb3 bb3: %ret = phi i32 [ %y, %bb2 ], [ %x, %bb1 ] ret i32 %ret } => declare void @f() define i32 @tgt2(i32 %x, i32 %y) { bb1: %cond = trunc nuw i32 %x to i1 br i1 %cond, label %bb2, label %bb3 bb2: call void @f() br label %bb3 bb3: %ret = phi i32 [ %y, %bb2 ], [ 0, %bb1 ] ret i32 %ret } Transformation seems to be correct! Summary: 2 correct transformations 0 incorrect transformations 0 failed-to-prove transformations 0 Alive2 errors ```
HendrikHuebner commented 2 days ago

I'd like to work on this