Skip to content

Commit 0a37290

Browse files
committed
[InstSimplify] restrict logic fold with partial undef vector
https://alive2.llvm.org/ce/z/4ncsnX Fixes #58977
1 parent cd7ff07 commit 0a37290

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2241,7 +2241,7 @@ static Value *simplifyOrLogic(Value *X, Value *Y) {
22412241
// (B ^ ~A) | (A & B) --> B ^ ~A
22422242
// (~A ^ B) | (B & A) --> ~A ^ B
22432243
// (B ^ ~A) | (B & A) --> B ^ ~A
2244-
if (match(X, m_c_Xor(m_Not(m_Value(A)), m_Value(B))) &&
2244+
if (match(X, m_c_Xor(m_NotForbidUndef(m_Value(A)), m_Value(B))) &&
22452245
match(Y, m_c_And(m_Specific(A), m_Specific(B))))
22462246
return X;
22472247

llvm/test/Transforms/InstSimplify/AndOrXor.ll

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,9 +680,26 @@ define i3 @or_xorn_and_commute1(i3 %a, i3 %b) {
680680

681681
define <2 x i32> @or_xorn_and_commute2(<2 x i32> %a, <2 x i32> %b) {
682682
; CHECK-LABEL: @or_xorn_and_commute2(
683-
; CHECK-NEXT: [[NEGA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 undef, i32 -1>
683+
; CHECK-NEXT: [[NEGA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 -1, i32 -1>
684684
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[B:%.*]], [[NEGA]]
685685
; CHECK-NEXT: ret <2 x i32> [[XOR]]
686+
;
687+
%nega = xor <2 x i32> %a, <i32 -1, i32 -1>
688+
%and = and <2 x i32> %b, %a
689+
%xor = xor <2 x i32> %b, %nega
690+
%or = or <2 x i32> %xor, %and
691+
ret <2 x i32> %or
692+
}
693+
694+
; This is not safe to fold because the extra logic ops limit the undef-ness of the result.
695+
696+
define <2 x i32> @or_xorn_and_commute2_undef(<2 x i32> %a, <2 x i32> %b) {
697+
; CHECK-LABEL: @or_xorn_and_commute2_undef(
698+
; CHECK-NEXT: [[NEGA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 undef, i32 -1>
699+
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[B:%.*]], [[A]]
700+
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[B]], [[NEGA]]
701+
; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[XOR]], [[AND]]
702+
; CHECK-NEXT: ret <2 x i32> [[OR]]
686703
;
687704
%nega = xor <2 x i32> %a, <i32 undef, i32 -1>
688705
%and = and <2 x i32> %b, %a
@@ -691,6 +708,23 @@ define <2 x i32> @or_xorn_and_commute2(<2 x i32> %a, <2 x i32> %b) {
691708
ret <2 x i32> %or
692709
}
693710

711+
; TODO: Unlike the above test, this is safe to fold.
712+
713+
define <2 x i32> @or_xorn_and_commute2_poison(<2 x i32> %a, <2 x i32> %b) {
714+
; CHECK-LABEL: @or_xorn_and_commute2_poison(
715+
; CHECK-NEXT: [[NEGA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 poison, i32 -1>
716+
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[B:%.*]], [[A]]
717+
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[B]], [[NEGA]]
718+
; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[XOR]], [[AND]]
719+
; CHECK-NEXT: ret <2 x i32> [[OR]]
720+
;
721+
%nega = xor <2 x i32> %a, <i32 poison, i32 -1>
722+
%and = and <2 x i32> %b, %a
723+
%xor = xor <2 x i32> %b, %nega
724+
%or = or <2 x i32> %xor, %and
725+
ret <2 x i32> %or
726+
}
727+
694728
define i32 @or_xorn_and_commute3(i32 %a, i32 %b) {
695729
; CHECK-LABEL: @or_xorn_and_commute3(
696730
; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1

0 commit comments

Comments
 (0)