-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Miscompile, probably due to DAGCombiner turning SELECT into AND even if the SELECT operands may be poison #84653
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
Labels
Comments
I forgot to write that the difference we see, after the improvement in ValueTracking in 17162b6, is that the SMAX will be folded away.
while we used to get
The smax is needed to get correct behavior when the sub (later rewritten as xor) has signed wrap. |
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Mar 12, 2024
Work-in-progress, to fix llvm#84653
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Mar 13, 2024
Work-in-progress, to fix llvm#84653
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Mar 15, 2024
Adding reproducers for github issues llvm#84653 and llvm#85190.
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Mar 15, 2024
Just like for regular IR we need to treat SELECT as conditionally blocking poison. So (unless the condition itself is poison) the result is only poison if the selected true/false value is poison. Thus, when doing DAG combines that turn SELECT into arithmetic/logical operations (e.g. AND/OR) we need to make sure that the new operations aren't more poisonous. One way to do that is to use FREEZE to make sure the operands aren't posion. This patch aims at fixing the kind of miscompiles reported in llvm#84653 and llvm#85190 Solution is to make sure that we insert FREEZE, if needed to make the fold sound, when using the foldBoolSelectToLogic and foldVSelectToSignBitSplatMask DAG combines. This may result in some (hopefully minor) regressions since we lack some ways to fold away the freeze (or due to isGuaranteedNotToBePoison being too pessimistic). Focus in this patch is to just avoid miscompiles, but I think some of the regressions can be avoided by general improvements regarding poison/freeze handling in SelectionDAG.
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Mar 20, 2024
The description of CopyFromReg in ISDOpcodes.h says that the input valus is defined outside the scope of the current SelectionDAG. I think that means that we basically can treat it as a FREEZE in the sense that it can be seen as neither being undef nor poison. Being able to fold freeze(CopyFromReg) into CopyFromReg seems useful to avoid regressions if we start to introduce freeze instruction in DAGCombiner/foldBoolSelectToLogic, e.g. to solve llvm#84653 Things _not_ dealt with in this patch: - Depending on calling convention an input argument can be passed also on the stack and not in a register. If it is allowed to treat an argument received in a register as not being poison, then I think we want to treat arguments received on the stack the same way. But then we need to attribute load instructions, or add explicit FREEZE when lowering formal arguments. - A common pattern is that there is an AssertZext or AssertSext just after CopyFromReg. I think that if we treat CopyFromReg as never being poison, then it should be allowed to fold (freeze(AssertZext(CopyFromReg))) -> AssertZext(CopyFromReg))
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Apr 9, 2024
Adding reproducers for github issues llvm#84653 and llvm#85190.
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Apr 9, 2024
Just like for regular IR we need to treat SELECT as conditionally blocking poison. So (unless the condition itself is poison) the result is only poison if the selected true/false value is poison. Thus, when doing DAG combines that turn SELECT into arithmetic/logical operations (e.g. AND/OR) we need to make sure that the new operations aren't more poisonous. One way to do that is to use FREEZE to make sure the operands aren't posion. This patch aims at fixing the kind of miscompiles reported in llvm#84653 and llvm#85190 Solution is to make sure that we insert FREEZE, if needed to make the fold sound, when using the foldBoolSelectToLogic and foldVSelectToSignBitSplatMask DAG combines. This may result in some (hopefully minor) regressions since we lack some ways to fold away the freeze (or due to isGuaranteedNotToBePoison being too pessimistic). Focus in this patch is to just avoid miscompiles, but I think some of the regressions can be avoided by general improvements regarding poison/freeze handling in SelectionDAG.
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Apr 9, 2024
Allow pushing freeze through SETCC and SELECT_CC even if there are multiple "maybe poison" operands. In the past we have limited it to a single "maybe poison" operand, but it seems profitable to also allow the multiple operand scenario. One goal here is to avoid some regressions seen in review of llvm#84924 when solving the select->and miscompiles described in llvm#84653
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Apr 24, 2024
The description of CopyFromReg in ISDOpcodes.h says that the input valus is defined outside the scope of the current SelectionDAG. I think that means that we basically can treat it as a FREEZE in the sense that it can be seen as neither being undef nor poison. Being able to fold freeze(CopyFromReg) into CopyFromReg seems useful to avoid regressions if we start to introduce freeze instruction in DAGCombiner/foldBoolSelectToLogic, e.g. to solve llvm#84653 Things _not_ dealt with in this patch: - Depending on calling convention an input argument can be passed also on the stack and not in a register. If it is allowed to treat an argument received in a register as not being poison, then I think we want to treat arguments received on the stack the same way. But then we need to attribute load instructions, or add explicit FREEZE when lowering formal arguments. - A common pattern is that there is an AssertZext or AssertSext just after CopyFromReg. I think that if we treat CopyFromReg as never being poison, then it should be allowed to fold (freeze(AssertZext(CopyFromReg))) -> AssertZext(CopyFromReg))
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Apr 26, 2024
The description of CopyFromReg in ISDOpcodes.h says that the input valus is defined outside the scope of the current SelectionDAG. I think that means that we basically can treat it as a FREEZE in the sense that it can be seen as neither being undef nor poison. Being able to fold freeze(CopyFromReg) into CopyFromReg seems useful to avoid regressions if we start to introduce freeze instruction in DAGCombiner/foldBoolSelectToLogic, e.g. to solve llvm#84653 Things _not_ dealt with in this patch: - Depending on calling convention an input argument can be passed also on the stack and not in a register. If it is allowed to treat an argument received in a register as not being poison, then I think we want to treat arguments received on the stack the same way. But then we need to attribute load instructions, or add explicit FREEZE when lowering formal arguments. - A common pattern is that there is an AssertZext or AssertSext just after CopyFromReg. I think that if we treat CopyFromReg as never being poison, then it should be allowed to fold (freeze(AssertZext(CopyFromReg))) -> AssertZext(CopyFromReg))
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Apr 26, 2024
Just like for regular IR we need to treat SELECT as conditionally blocking poison. So (unless the condition itself is poison) the result is only poison if the selected true/false value is poison. Thus, when doing DAG combines that turn SELECT into arithmetic/logical operations (e.g. AND/OR) we need to make sure that the new operations aren't more poisonous. One way to do that is to use FREEZE to make sure the operands aren't posion. This patch aims at fixing the kind of miscompiles reported in llvm#84653 and llvm#85190 Solution is to make sure that we insert FREEZE, if needed to make the fold sound, when using the foldBoolSelectToLogic and foldVSelectToSignBitSplatMask DAG combines. This may result in some (hopefully minor) regressions since we lack some ways to fold away the freeze (or due to isGuaranteedNotToBePoison being too pessimistic). Focus in this patch is to just avoid miscompiles, but I think some of the regressions can be avoided by general improvements regarding poison/freeze handling in SelectionDAG.
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Apr 26, 2024
Allow pushing freeze through SETCC and SELECT_CC even if there are multiple "maybe poison" operands. In the past we have limited it to a single "maybe poison" operand, but it seems profitable to also allow the multiple operand scenario. One goal here is to avoid some regressions seen in review of llvm#84924 when solving the select->and miscompiles described in llvm#84653
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
May 28, 2024
Just like for regular IR we need to treat SELECT as conditionally blocking poison. So (unless the condition itself is poison) the result is only poison if the selected true/false value is poison. Thus, when doing DAG combines that turn SELECT into arithmetic/logical operations (e.g. AND/OR) we need to make sure that the new operations aren't more poisonous. One way to do that is to use FREEZE to make sure the operands aren't posion. This patch aims at fixing the kind of miscompiles reported in llvm#84653 and llvm#85190 Solution is to make sure that we insert FREEZE, if needed to make the fold sound, when using the foldBoolSelectToLogic and foldVSelectToSignBitSplatMask DAG combines. This may result in some (hopefully minor) regressions since we lack some ways to fold away the freeze (or due to isGuaranteedNotToBePoison being too pessimistic). Focus in this patch is to just avoid miscompiles, but I think some of the regressions can be avoided by general improvements regarding poison/freeze handling in SelectionDAG.
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
May 28, 2024
Allow pushing freeze through SETCC and SELECT_CC even if there are multiple "maybe poison" operands. In the past we have limited it to a single "maybe poison" operand, but it seems profitable to also allow the multiple operand scenario. One goal here is to avoid some regressions seen in review of llvm#84924 when solving the select->and miscompiles described in llvm#84653
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
May 29, 2024
Allow pushing freeze through SETCC and SELECT_CC even if there are multiple "maybe poison" operands. In the past we have limited it to a single "maybe poison" operand, but it seems profitable to also allow the multiple operand scenario. One goal here is to avoid some regressions seen in review of llvm#84924 when solving the select->and miscompiles described in llvm#84653
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Jul 19, 2024
Just like for regular IR we need to treat SELECT as conditionally blocking poison. So (unless the condition itself is poison) the result is only poison if the selected true/false value is poison. Thus, when doing DAG combines that turn SELECT into arithmetic/logical operations (e.g. AND/OR) we need to make sure that the new operations aren't more poisonous. One way to do that is to use FREEZE to make sure the operands aren't posion. This patch aims at fixing the kind of miscompiles reported in llvm#84653 and llvm#85190 Solution is to make sure that we insert FREEZE, if needed to make the fold sound, when using the foldBoolSelectToLogic and foldVSelectToSignBitSplatMask DAG combines.
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Jul 22, 2024
Just like for regular IR we need to treat SELECT as conditionally blocking poison. So (unless the condition itself is poison) the result is only poison if the selected true/false value is poison. Thus, when doing DAG combines that turn SELECT into arithmetic/logical operations (e.g. AND/OR) we need to make sure that the new operations aren't more poisonous. One way to do that is to use FREEZE to make sure the operands aren't posion. This patch aims at fixing the kind of miscompiles reported in llvm#84653 and llvm#85190 Solution is to make sure that we insert FREEZE, if needed to make the fold sound, when using the foldBoolSelectToLogic and foldVSelectToSignBitSplatMask DAG combines.
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Jul 22, 2024
Allow pushing freeze through SETCC and SELECT_CC even if there are multiple "maybe poison" operands. In the past we have limited it to a single "maybe poison" operand, but it seems profitable to also allow the multiple operand scenario. One goal here is to avoid some regressions seen in review of llvm#84924 when solving the select->and miscompiles described in llvm#84653
bjope
added a commit
to bjope/llvm-project
that referenced
this issue
Jul 22, 2024
Just like for regular IR we need to treat SELECT as conditionally blocking poison. So (unless the condition itself is poison) the result is only poison if the selected true/false value is poison. Thus, when doing DAG combines that turn SELECT into arithmetic/logical operations (e.g. AND/OR) we need to make sure that the new operations aren't more poisonous. One way to do that is to use FREEZE to make sure the operands aren't posion. This patch aims at fixing the kind of miscompiles reported in llvm#84653 and llvm#85190 Solution is to make sure that we insert FREEZE, if needed to make the fold sound, when using the foldBoolSelectToLogic and foldVSelectToSignBitSplatMask DAG combines.
bjope
added a commit
that referenced
this issue
Jul 22, 2024
…ic (#84924) Just like for regular IR we need to treat SELECT as conditionally blocking poison in SelectionDAG. So (unless the condition itself is poison) the result is only poison if the selected true/false value is poison. Thus, when doing DAG combines that turn SELECT into arithmetic/logical operations (e.g. AND/OR) we need to make sure that the new operations aren't more poisonous. One way to do that is to use FREEZE to make sure the operands aren't posion. This patch aims at fixing the kind of miscompiles reported in #84653 and #85190 Solution is to make sure that we insert FREEZE, if needed to make the fold sound, when using the foldBoolSelectToLogic and foldVSelectToSignBitSplatMask DAG combines.
yuxuanchen1997
pushed a commit
that referenced
this issue
Jul 25, 2024
Summary: Allow pushing freeze through SETCC and SELECT_CC even if there are multiple "maybe poison" operands. In the past we have limited it to a single "maybe poison" operand, but it seems profitable to also allow the multiple operand scenario. One goal here is to avoid some regressions seen in review of #84924 when solving the select->and miscompiles described in #84653 Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251168
yuxuanchen1997
pushed a commit
that referenced
this issue
Jul 25, 2024
…ic (#84924) Just like for regular IR we need to treat SELECT as conditionally blocking poison in SelectionDAG. So (unless the condition itself is poison) the result is only poison if the selected true/false value is poison. Thus, when doing DAG combines that turn SELECT into arithmetic/logical operations (e.g. AND/OR) we need to make sure that the new operations aren't more poisonous. One way to do that is to use FREEZE to make sure the operands aren't posion. This patch aims at fixing the kind of miscompiles reported in #84653 and #85190 Solution is to make sure that we insert FREEZE, if needed to make the fold sound, when using the foldBoolSelectToLogic and foldVSelectToSignBitSplatMask DAG combines.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Given a test case like this:
we started to see miscompiles after improvements to ValueTracking/KnownBits in 17162b6
Here is a godbolt link using aarch64 as an example (need mattr=+cssc to get a legal SMAX for i32): https://godbolt.org/z/8zxa4YEs5
When using
llc -debug-only=isel,dagcombine -mtriple=aarch64 -mattr=+cssc
one can see that we get an initial DAG like this:Then the DAGCombiner (foldBoolSelectToLogic) will do
which I think might be wrong depending on if we see such an AND as a logical/bitwise AND (or rather if it blocks poison or not).
What happens next is that that the AND is combined into a SMAX and a new SETCC:
And here it is clear that if the sub result in poison, then the result is poison as well.
On a side note. It is a bit sad that the last couple of years more and more things that can "produce poison" (such as nsw/nuw/nneg) are being exposed in the selection DAG, while I think we lack lots of documentation about what the rules are when it comes to dealing with poison in the selection DAG.
The text was updated successfully, but these errors were encountered: