-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[DAGCombiner] Don't ignore N2's undef elements in foldVSelectOfConstants
#129272
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
Conversation
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-llvm-selectiondag Author: Yingwei Zheng (dtcxzyw) ChangesSince N2 will be reused in the fold, we cannot skip N2's undef elements if the corresponding element in N1 is well-defined.
Before this patch, we fold t11 into:
The last element of t27 is incorrect. Closes #129181. Full diff: https://github.com/llvm/llvm-project/pull/129272.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index f197ae61550a9..343a93785766c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12535,9 +12535,10 @@ SDValue DAGCombiner::foldVSelectOfConstants(SDNode *N) {
for (unsigned i = 0; i != Elts; ++i) {
SDValue N1Elt = N1.getOperand(i);
SDValue N2Elt = N2.getOperand(i);
- if (N1Elt.isUndef() || N2Elt.isUndef())
+ if (N1Elt.isUndef())
continue;
- if (N1Elt.getValueType() != N2Elt.getValueType()) {
+ // N2 should not contain undef values since it will be reused in the fold.
+ if (N2Elt.isUndef() || N1Elt.getValueType() != N2Elt.getValueType()) {
AllAddOne = false;
AllSubOne = false;
break;
diff --git a/llvm/test/CodeGen/X86/vselect-constants.ll b/llvm/test/CodeGen/X86/vselect-constants.ll
index 901f7e4a00eb5..34bda718db8f6 100644
--- a/llvm/test/CodeGen/X86/vselect-constants.ll
+++ b/llvm/test/CodeGen/X86/vselect-constants.ll
@@ -302,3 +302,21 @@ define i32 @wrong_min_signbits(<2 x i16> %x) {
%t1 = bitcast <2 x i16> %sel to i32
ret i32 %t1
}
+
+define i32 @pr129181() {
+; SSE-LABEL: pr129181:
+; SSE: # %bb.0: # %entry
+; SSE-NEXT: xorl %eax, %eax
+; SSE-NEXT: retq
+;
+; AVX-LABEL: pr129181:
+; AVX: # %bb.0: # %entry
+; AVX-NEXT: xorl %eax, %eax
+; AVX-NEXT: retq
+entry:
+ %x = insertelement <4 x i32> zeroinitializer, i32 0, i32 0
+ %cmp = icmp ult <4 x i32> %x, splat (i32 1)
+ %sel = select <4 x i1> %cmp, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 0, i32 1, i32 poison>
+ %reduce = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %sel)
+ ret i32 %reduce
+}
|
You can test this locally with the following command:git diff -U0 --pickaxe-regex -S '([^a-zA-Z0-9#_-]undef[^a-zA-Z0-9_-]|UndefValue::get)' 78aa61d8b60fc3e9d00236332078d14808abbc57 1bc745841ee18b901b6e47edebefe4fd864c5e40 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/test/CodeGen/X86/vselect-constants.ll The following files introduce new uses of undef:
Undef is now deprecated and should only be used in the rare cases where no replacement is possible. For example, a load of uninitialized memory yields In tests, avoid using For example, this is considered a bad practice: define void @fn() {
...
br i1 undef, ...
} Please use the following instead: define void @fn(i1 %cond) {
...
br i1 %cond, ...
} Please refer to the Undefined Behavior Manual for more information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - cheers
/cherry-pick 2709366 |
/pull-request #129383 |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/13557 Here is the relevant piece of the build log for the reference
|
…ants` (llvm#129272) Since N2 will be reused in the fold, we cannot skip N2's undef elements if the corresponding element in N1 is well-defined. For example: ``` t2: v4i32 = BUILD_VECTOR Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0> t24: v4i32 = BUILD_VECTOR undef:i32, undef:i32, Constant:i32<1>, undef:i32 t11: v4i32 = vselect t8, t2, t10 ``` Before this patch, we fold t11 into: ``` t26: v4i32 = sign_extend t8 t27: v4i32 = add t26, t24 ``` The last element of t27 is incorrect. Closes llvm#129181. (cherry picked from commit 2709366)
…ants` (llvm#129272) Since N2 will be reused in the fold, we cannot skip N2's undef elements if the corresponding element in N1 is well-defined. For example: ``` t2: v4i32 = BUILD_VECTOR Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0> t24: v4i32 = BUILD_VECTOR undef:i32, undef:i32, Constant:i32<1>, undef:i32 t11: v4i32 = vselect t8, t2, t10 ``` Before this patch, we fold t11 into: ``` t26: v4i32 = sign_extend t8 t27: v4i32 = add t26, t24 ``` The last element of t27 is incorrect. Closes llvm#129181.
Since N2 will be reused in the fold, we cannot skip N2's undef elements if the corresponding element in N1 is well-defined.
For example:
Before this patch, we fold t11 into:
The last element of t27 is incorrect.
Closes #129181.