Skip to content

Commit 2b3376f

Browse files
authored
[InstCombine] Guard noundef for transformation from xor to or disjoint (#96905)
Fix #96857
1 parent da24d3a commit 2b3376f

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4616,8 +4616,12 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
46164616
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
46174617
Value *M;
46184618
if (match(&I, m_c_Xor(m_c_And(m_Not(m_Value(M)), m_Value()),
4619-
m_c_And(m_Deferred(M), m_Value()))))
4620-
return BinaryOperator::CreateDisjointOr(Op0, Op1);
4619+
m_c_And(m_Deferred(M), m_Value())))) {
4620+
if (isGuaranteedNotToBeUndef(M))
4621+
return BinaryOperator::CreateDisjointOr(Op0, Op1);
4622+
else
4623+
return BinaryOperator::CreateOr(Op0, Op1);
4624+
}
46214625

46224626
if (Instruction *Xor = visitMaskedMerge(I, Builder))
46234627
return Xor;

llvm/test/Transforms/InstCombine/xor.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,3 +1453,35 @@ define i32 @tryFactorization_xor_ashr_ashr(i32 %a) {
14531453
%xor = xor i32 %not, %shr1
14541454
ret i32 %xor
14551455
}
1456+
1457+
; https://alive2.llvm.org/ce/z/SOxv-e
1458+
define i4 @PR96857_xor_with_noundef(i4 %val0, i4 %val1, i4 noundef %val2) {
1459+
; CHECK-LABEL: @PR96857_xor_with_noundef(
1460+
; CHECK-NEXT: [[VAL4:%.*]] = and i4 [[VAL2:%.*]], [[VAL0:%.*]]
1461+
; CHECK-NEXT: [[VAL5:%.*]] = xor i4 [[VAL2]], -1
1462+
; CHECK-NEXT: [[VAL6:%.*]] = and i4 [[VAL5]], [[VAL1:%.*]]
1463+
; CHECK-NEXT: [[VAL7:%.*]] = or disjoint i4 [[VAL4]], [[VAL6]]
1464+
; CHECK-NEXT: ret i4 [[VAL7]]
1465+
;
1466+
%val4 = and i4 %val2, %val0
1467+
%val5 = xor i4 %val2, -1
1468+
%val6 = and i4 %val5, %val1
1469+
%val7 = xor i4 %val4, %val6
1470+
ret i4 %val7
1471+
}
1472+
1473+
; https://alive2.llvm.org/ce/z/whLTaJ
1474+
define i4 @PR96857_xor_without_noundef(i4 %val0, i4 %val1, i4 %val2) {
1475+
; CHECK-LABEL: @PR96857_xor_without_noundef(
1476+
; CHECK-NEXT: [[VAL4:%.*]] = and i4 [[VAL2:%.*]], [[VAL0:%.*]]
1477+
; CHECK-NEXT: [[VAL5:%.*]] = xor i4 [[VAL2]], -1
1478+
; CHECK-NEXT: [[VAL6:%.*]] = and i4 [[VAL5]], [[VAL1:%.*]]
1479+
; CHECK-NEXT: [[VAL7:%.*]] = or i4 [[VAL4]], [[VAL6]]
1480+
; CHECK-NEXT: ret i4 [[VAL7]]
1481+
;
1482+
%val4 = and i4 %val2, %val0
1483+
%val5 = xor i4 %val2, -1
1484+
%val6 = and i4 %val5, %val1
1485+
%val7 = xor i4 %val4, %val6
1486+
ret i4 %val7
1487+
}

0 commit comments

Comments
 (0)