Skip to content

Commit 5c3496f

Browse files
authored
[InstCombine] Check isGuaranteedNotToBeUndef in haveNoCommonBitsSetSpecialCases. (llvm#74390)
It's not safe for InstCombine to add disjoint metadata when converting Add to Or otherwise. I've added noundef attribute to preserve existing test behavior.
1 parent 3c5b42a commit 5c3496f

File tree

9 files changed

+87
-79
lines changed

9 files changed

+87
-79
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -186,37 +186,45 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
186186
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
187187
}
188188

189-
static bool haveNoCommonBitsSetSpecialCases(const Value *LHS,
190-
const Value *RHS) {
189+
static bool haveNoCommonBitsSetSpecialCases(const Value *LHS, const Value *RHS,
190+
const SimplifyQuery &SQ) {
191191
// Look for an inverted mask: (X & ~M) op (Y & M).
192192
{
193193
Value *M;
194194
if (match(LHS, m_c_And(m_Not(m_Value(M)), m_Value())) &&
195-
match(RHS, m_c_And(m_Specific(M), m_Value())))
195+
match(RHS, m_c_And(m_Specific(M), m_Value())) &&
196+
isGuaranteedNotToBeUndef(M, SQ.AC, SQ.CxtI, SQ.DT))
196197
return true;
197198
}
198199

199200
// X op (Y & ~X)
200-
if (match(RHS, m_c_And(m_Not(m_Specific(LHS)), m_Value())))
201+
if (match(RHS, m_c_And(m_Not(m_Specific(LHS)), m_Value())) &&
202+
isGuaranteedNotToBeUndef(LHS, SQ.AC, SQ.CxtI, SQ.DT))
201203
return true;
202204

203205
// X op ((X & Y) ^ Y) -- this is the canonical form of the previous pattern
204206
// for constant Y.
205207
Value *Y;
206-
if (match(RHS, m_c_Xor(m_c_And(m_Specific(LHS), m_Value(Y)), m_Deferred(Y))))
208+
if (match(RHS,
209+
m_c_Xor(m_c_And(m_Specific(LHS), m_Value(Y)), m_Deferred(Y))) &&
210+
isGuaranteedNotToBeUndef(LHS, SQ.AC, SQ.CxtI, SQ.DT) &&
211+
isGuaranteedNotToBeUndef(Y, SQ.AC, SQ.CxtI, SQ.DT))
207212
return true;
208213

209214
// Peek through extends to find a 'not' of the other side:
210215
// (ext Y) op ext(~Y)
211216
if (match(LHS, m_ZExtOrSExt(m_Value(Y))) &&
212-
match(RHS, m_ZExtOrSExt(m_Not(m_Specific(Y)))))
217+
match(RHS, m_ZExtOrSExt(m_Not(m_Specific(Y)))) &&
218+
isGuaranteedNotToBeUndef(Y, SQ.AC, SQ.CxtI, SQ.DT))
213219
return true;
214220

215221
// Look for: (A & B) op ~(A | B)
216222
{
217223
Value *A, *B;
218224
if (match(LHS, m_And(m_Value(A), m_Value(B))) &&
219-
match(RHS, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
225+
match(RHS, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))) &&
226+
isGuaranteedNotToBeUndef(A, SQ.AC, SQ.CxtI, SQ.DT) &&
227+
isGuaranteedNotToBeUndef(B, SQ.AC, SQ.CxtI, SQ.DT))
220228
return true;
221229
}
222230

@@ -234,8 +242,8 @@ bool llvm::haveNoCommonBitsSet(const WithCache<const Value *> &LHSCache,
234242
assert(LHS->getType()->isIntOrIntVectorTy() &&
235243
"LHS and RHS should be integers");
236244

237-
if (haveNoCommonBitsSetSpecialCases(LHS, RHS) ||
238-
haveNoCommonBitsSetSpecialCases(RHS, LHS))
245+
if (haveNoCommonBitsSetSpecialCases(LHS, RHS, SQ) ||
246+
haveNoCommonBitsSetSpecialCases(RHS, LHS, SQ))
239247
return true;
240248

241249
return KnownBits::haveNoCommonBitsSet(LHSCache.getKnownBits(SQ),

llvm/test/Transforms/InstCombine/add.ll

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,7 +1521,7 @@ define i8 @add_like_or_disjoint(i8 %x) {
15211521
ret i8 %r
15221522
}
15231523

1524-
define i8 @add_and_xor(i8 %x, i8 %y) {
1524+
define i8 @add_and_xor(i8 noundef %x, i8 %y) {
15251525
; CHECK-LABEL: @add_and_xor(
15261526
; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
15271527
; CHECK-NEXT: ret i8 [[ADD]]
@@ -1558,7 +1558,7 @@ define i8 @add_and_xor_wrong_op(i8 %x, i8 %y, i8 %z) {
15581558
ret i8 %add
15591559
}
15601560

1561-
define i8 @add_and_xor_commuted1(i8 %x, i8 %_y) {
1561+
define i8 @add_and_xor_commuted1(i8 noundef %x, i8 %_y) {
15621562
; CHECK-LABEL: @add_and_xor_commuted1(
15631563
; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
15641564
; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X:%.*]]
@@ -1571,7 +1571,7 @@ define i8 @add_and_xor_commuted1(i8 %x, i8 %_y) {
15711571
ret i8 %add
15721572
}
15731573

1574-
define i8 @add_and_xor_commuted2(i8 %_x, i8 %y) {
1574+
define i8 @add_and_xor_commuted2(i8 noundef %_x, i8 %y) {
15751575
; CHECK-LABEL: @add_and_xor_commuted2(
15761576
; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
15771577
; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y:%.*]]
@@ -1584,7 +1584,7 @@ define i8 @add_and_xor_commuted2(i8 %_x, i8 %y) {
15841584
ret i8 %add
15851585
}
15861586

1587-
define i8 @add_and_xor_commuted3(i8 %_x, i8 %_y) {
1587+
define i8 @add_and_xor_commuted3(i8 noundef %_x, i8 %_y) {
15881588
; CHECK-LABEL: @add_and_xor_commuted3(
15891589
; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
15901590
; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
@@ -1599,7 +1599,7 @@ define i8 @add_and_xor_commuted3(i8 %_x, i8 %_y) {
15991599
ret i8 %add
16001600
}
16011601

1602-
define i8 @add_and_xor_extra_use(i8 %x, i8 %y) {
1602+
define i8 @add_and_xor_extra_use(i8 noundef %x, i8 %y) {
16031603
; CHECK-LABEL: @add_and_xor_extra_use(
16041604
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1
16051605
; CHECK-NEXT: call void @use(i8 [[XOR]])
@@ -1616,7 +1616,7 @@ define i8 @add_and_xor_extra_use(i8 %x, i8 %y) {
16161616
ret i8 %add
16171617
}
16181618

1619-
define i8 @add_xor_and_const(i8 %x) {
1619+
define i8 @add_xor_and_const(i8 noundef %x) {
16201620
; CHECK-LABEL: @add_xor_and_const(
16211621
; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X:%.*]], 42
16221622
; CHECK-NEXT: ret i8 [[ADD]]
@@ -1640,7 +1640,7 @@ define i8 @add_xor_and_const_wrong_const(i8 %x) {
16401640
ret i8 %add
16411641
}
16421642

1643-
define i8 @add_xor_and_var(i8 %x, i8 %y) {
1643+
define i8 @add_xor_and_var(i8 noundef %x, i8 noundef %y) {
16441644
; CHECK-LABEL: @add_xor_and_var(
16451645
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
16461646
; CHECK-NEXT: call void @use(i8 [[AND]])
@@ -1684,7 +1684,7 @@ define i8 @add_xor_and_var_wrong_op2(i8 %x, i8 %y, i8 %z) {
16841684
ret i8 %add
16851685
}
16861686

1687-
define i8 @add_xor_and_var_commuted1(i8 %x, i8 %y) {
1687+
define i8 @add_xor_and_var_commuted1(i8 noundef %x, i8 noundef %y) {
16881688
; CHECK-LABEL: @add_xor_and_var_commuted1(
16891689
; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]
16901690
; CHECK-NEXT: call void @use(i8 [[AND]])
@@ -1698,7 +1698,7 @@ define i8 @add_xor_and_var_commuted1(i8 %x, i8 %y) {
16981698
ret i8 %add
16991699
}
17001700

1701-
define i8 @add_xor_and_var_commuted2(i8 %_x, i8 %_y) {
1701+
define i8 @add_xor_and_var_commuted2(i8 noundef %_x, i8 noundef %_y) {
17021702
; CHECK-LABEL: @add_xor_and_var_commuted2(
17031703
; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
17041704
; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
@@ -1716,7 +1716,7 @@ define i8 @add_xor_and_var_commuted2(i8 %_x, i8 %_y) {
17161716
ret i8 %add
17171717
}
17181718

1719-
define i8 @add_xor_and_var_commuted3(i8 %x, i8 %_y) {
1719+
define i8 @add_xor_and_var_commuted3(i8 noundef %x, i8 noundef %_y) {
17201720
; CHECK-LABEL: @add_xor_and_var_commuted3(
17211721
; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
17221722
; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X:%.*]]
@@ -1732,7 +1732,7 @@ define i8 @add_xor_and_var_commuted3(i8 %x, i8 %_y) {
17321732
ret i8 %add
17331733
}
17341734

1735-
define i8 @add_xor_and_var_commuted4(i8 %_x, i8 %y) {
1735+
define i8 @add_xor_and_var_commuted4(i8 noundef %_x, i8 noundef %y) {
17361736
; CHECK-LABEL: @add_xor_and_var_commuted4(
17371737
; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
17381738
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y:%.*]]
@@ -1748,7 +1748,7 @@ define i8 @add_xor_and_var_commuted4(i8 %_x, i8 %y) {
17481748
ret i8 %add
17491749
}
17501750

1751-
define i8 @add_xor_and_var_commuted5(i8 %_x, i8 %_y) {
1751+
define i8 @add_xor_and_var_commuted5(i8 noundef %_x, i8 noundef %_y) {
17521752
; CHECK-LABEL: @add_xor_and_var_commuted5(
17531753
; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
17541754
; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
@@ -1766,7 +1766,7 @@ define i8 @add_xor_and_var_commuted5(i8 %_x, i8 %_y) {
17661766
ret i8 %add
17671767
}
17681768

1769-
define i8 @add_xor_and_var_commuted6(i8 %_x, i8 %_y) {
1769+
define i8 @add_xor_and_var_commuted6(i8 noundef %_x, i8 noundef %_y) {
17701770
; CHECK-LABEL: @add_xor_and_var_commuted6(
17711771
; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
17721772
; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
@@ -1784,7 +1784,7 @@ define i8 @add_xor_and_var_commuted6(i8 %_x, i8 %_y) {
17841784
ret i8 %add
17851785
}
17861786

1787-
define i8 @add_xor_and_var_commuted7(i8 %_x, i8 %_y) {
1787+
define i8 @add_xor_and_var_commuted7(i8 noundef %_x, i8 noundef %_y) {
17881788
; CHECK-LABEL: @add_xor_and_var_commuted7(
17891789
; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
17901790
; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
@@ -1802,7 +1802,7 @@ define i8 @add_xor_and_var_commuted7(i8 %_x, i8 %_y) {
18021802
ret i8 %add
18031803
}
18041804

1805-
define i8 @add_xor_and_var_extra_use(i8 %x, i8 %y) {
1805+
define i8 @add_xor_and_var_extra_use(i8 noundef %x, i8 noundef %y) {
18061806
; CHECK-LABEL: @add_xor_and_var_extra_use(
18071807
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
18081808
; CHECK-NEXT: call void @use(i8 [[AND]])
@@ -2583,7 +2583,7 @@ define <vscale x 1 x i32> @add_to_or_scalable(<vscale x 1 x i32> %in) {
25832583
ret <vscale x 1 x i32> %add
25842584
}
25852585

2586-
define i5 @zext_zext_not(i3 %x) {
2586+
define i5 @zext_zext_not(i3 noundef %x) {
25872587
; CHECK-LABEL: @zext_zext_not(
25882588
; CHECK-NEXT: ret i5 7
25892589
;
@@ -2594,7 +2594,7 @@ define i5 @zext_zext_not(i3 %x) {
25942594
ret i5 %r
25952595
}
25962596

2597-
define <2 x i5> @zext_zext_not_commute(<2 x i3> %x) {
2597+
define <2 x i5> @zext_zext_not_commute(<2 x i3> noundef %x) {
25982598
; CHECK-LABEL: @zext_zext_not_commute(
25992599
; CHECK-NEXT: ret <2 x i5> <i5 7, i5 7>
26002600
;
@@ -2605,7 +2605,7 @@ define <2 x i5> @zext_zext_not_commute(<2 x i3> %x) {
26052605
ret <2 x i5> %r
26062606
}
26072607

2608-
define i9 @sext_sext_not(i3 %x) {
2608+
define i9 @sext_sext_not(i3 noundef %x) {
26092609
; CHECK-LABEL: @sext_sext_not(
26102610
; CHECK-NEXT: ret i9 -1
26112611
;
@@ -2616,7 +2616,7 @@ define i9 @sext_sext_not(i3 %x) {
26162616
ret i9 %r
26172617
}
26182618

2619-
define i8 @sext_sext_not_commute(i3 %x) {
2619+
define i8 @sext_sext_not_commute(i3 noundef %x) {
26202620
; CHECK-LABEL: @sext_sext_not_commute(
26212621
; CHECK-NEXT: [[SX:%.*]] = sext i3 [[X:%.*]] to i8
26222622
; CHECK-NEXT: call void @use(i8 [[SX]])
@@ -2631,7 +2631,7 @@ define i8 @sext_sext_not_commute(i3 %x) {
26312631
ret i8 %r
26322632
}
26332633

2634-
define i5 @zext_sext_not(i4 %x) {
2634+
define i5 @zext_sext_not(i4 noundef %x) {
26352635
; CHECK-LABEL: @zext_sext_not(
26362636
; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i5
26372637
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
@@ -2646,7 +2646,7 @@ define i5 @zext_sext_not(i4 %x) {
26462646
ret i5 %r
26472647
}
26482648

2649-
define i8 @zext_sext_not_commute(i4 %x) {
2649+
define i8 @zext_sext_not_commute(i4 noundef %x) {
26502650
; CHECK-LABEL: @zext_sext_not_commute(
26512651
; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i8
26522652
; CHECK-NEXT: call void @use(i8 [[ZX]])
@@ -2665,7 +2665,7 @@ define i8 @zext_sext_not_commute(i4 %x) {
26652665
ret i8 %r
26662666
}
26672667

2668-
define i9 @sext_zext_not(i4 %x) {
2668+
define i9 @sext_zext_not(i4 noundef %x) {
26692669
; CHECK-LABEL: @sext_zext_not(
26702670
; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9
26712671
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
@@ -2680,7 +2680,7 @@ define i9 @sext_zext_not(i4 %x) {
26802680
ret i9 %r
26812681
}
26822682

2683-
define i9 @sext_zext_not_commute(i4 %x) {
2683+
define i9 @sext_zext_not_commute(i4 noundef %x) {
26842684
; CHECK-LABEL: @sext_zext_not_commute(
26852685
; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9
26862686
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1

llvm/test/Transforms/InstCombine/and-or-not.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ define i32 @and_to_nxor_multiuse(float %fa, float %fb) {
548548

549549
; (a & b) | ~(a | b) --> ~(a ^ b)
550550
; TODO: this increases instruction count if the pieces have additional users
551-
define i32 @or_to_nxor_multiuse(i32 %a, i32 %b) {
551+
define i32 @or_to_nxor_multiuse(i32 noundef %a, i32 noundef %b) {
552552
; CHECK-LABEL: @or_to_nxor_multiuse(
553553
; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
554554
; CHECK-NEXT: [[OR:%.*]] = or i32 [[A]], [[B]]

llvm/test/Transforms/InstCombine/logical-select.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ define <vscale x 2 x i64> @bitcast_vec_cond_scalable(<vscale x 16 x i1> %cond, <
762762

763763
; Negative test - bitcast of condition from wide source element type cannot be converted to select.
764764

765-
define <8 x i3> @bitcast_vec_cond_commute1(<3 x i1> %cond, <8 x i3> %pc, <8 x i3> %d) {
765+
define <8 x i3> @bitcast_vec_cond_commute1(<3 x i1> noundef %cond, <8 x i3> %pc, <8 x i3> %d) {
766766
; CHECK-LABEL: @bitcast_vec_cond_commute1(
767767
; CHECK-NEXT: [[C:%.*]] = mul <8 x i3> [[PC:%.*]], [[PC]]
768768
; CHECK-NEXT: [[S:%.*]] = sext <3 x i1> [[COND:%.*]] to <3 x i8>
@@ -830,7 +830,7 @@ define <2 x i16> @bitcast_vec_cond_commute3(<4 x i8> %cond, <2 x i16> %pc, <2 x
830830

831831
; Don't crash on invalid type for compute signbits.
832832

833-
define <2 x i64> @bitcast_fp_vec_cond(<2 x double> %s, <2 x i64> %c, <2 x i64> %d) {
833+
define <2 x i64> @bitcast_fp_vec_cond(<2 x double> noundef %s, <2 x i64> %c, <2 x i64> %d) {
834834
; CHECK-LABEL: @bitcast_fp_vec_cond(
835835
; CHECK-NEXT: [[T9:%.*]] = bitcast <2 x double> [[S:%.*]] to <2 x i64>
836836
; CHECK-NEXT: [[NOTT9:%.*]] = xor <2 x i64> [[T9]], <i64 -1, i64 -1>
@@ -849,7 +849,7 @@ define <2 x i64> @bitcast_fp_vec_cond(<2 x double> %s, <2 x i64> %c, <2 x i64> %
849849

850850
; Wider source type would be ok except poison could leak across elements.
851851

852-
define <2 x i64> @bitcast_int_vec_cond(i1 %b, <2 x i64> %c, <2 x i64> %d) {
852+
define <2 x i64> @bitcast_int_vec_cond(i1 noundef %b, <2 x i64> %c, <2 x i64> %d) {
853853
; CHECK-LABEL: @bitcast_int_vec_cond(
854854
; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i128
855855
; CHECK-NEXT: [[T9:%.*]] = bitcast i128 [[S]] to <2 x i64>

0 commit comments

Comments
 (0)