Skip to content

Commit 65bf93d

Browse files
authored
[InstCombine] Clean up bitwise folds without one-use check (#80587)
This patch removes some bitwise folds that fail to check the one-use constraint on the operands. See also the comments #77231 (comment).
1 parent ab92f62 commit 65bf93d

File tree

3 files changed

+188
-23
lines changed

3 files changed

+188
-23
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3610,14 +3610,6 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
36103610
if (match(Op1, m_c_Xor(m_c_And(m_Value(A), m_Specific(Op0)), m_Value(C))))
36113611
return BinaryOperator::CreateOr(Op0, C);
36123612

3613-
// ((B | C) & A) | B -> B | (A & C)
3614-
if (match(Op0, m_c_And(m_c_Or(m_Specific(Op1), m_Value(C)), m_Value(A))))
3615-
return BinaryOperator::CreateOr(Op1, Builder.CreateAnd(A, C));
3616-
3617-
// B | ((B | C) & A) -> B | (A & C)
3618-
if (match(Op1, m_c_And(m_c_Or(m_Specific(Op0), m_Value(C)), m_Value(A))))
3619-
return BinaryOperator::CreateOr(Op0, Builder.CreateAnd(A, C));
3620-
36213613
if (Instruction *DeMorgan = matchDeMorgansLaws(I, *this))
36223614
return DeMorgan;
36233615

@@ -3670,17 +3662,6 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
36703662
Value *Nand = Builder.CreateNot(Builder.CreateAnd(A, B), "nand");
36713663
return BinaryOperator::CreateOr(Nand, C);
36723664
}
3673-
3674-
// A | (~A ^ B) --> ~B | A
3675-
// B | (A ^ ~B) --> ~A | B
3676-
if (Op1->hasOneUse() && match(A, m_Not(m_Specific(Op0)))) {
3677-
Value *NotB = Builder.CreateNot(B, B->getName() + ".not");
3678-
return BinaryOperator::CreateOr(NotB, Op0);
3679-
}
3680-
if (Op1->hasOneUse() && match(B, m_Not(m_Specific(Op0)))) {
3681-
Value *NotA = Builder.CreateNot(A, A->getName() + ".not");
3682-
return BinaryOperator::CreateOr(NotA, Op0);
3683-
}
36843665
}
36853666

36863667
// A | ~(A | B) -> A | ~B

llvm/test/Transforms/InstCombine/or-xor.ll

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,3 +1094,75 @@ define i32 @PR75692_3(i32 %x, i32 %y) {
10941094
%t4 = or i32 %t2, %t3
10951095
ret i32 %t4
10961096
}
1097+
1098+
define i32 @or_xor_not(i32 %x, i32 %y) {
1099+
; CHECK-LABEL: @or_xor_not(
1100+
; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
1101+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
1102+
; CHECK-NEXT: ret i32 [[OR1]]
1103+
;
1104+
%not = xor i32 %y, -1
1105+
%xor = xor i32 %x, %not
1106+
%or1 = or i32 %xor, %y
1107+
ret i32 %or1
1108+
}
1109+
1110+
define i32 @or_xor_not_uses1(i32 %x, i32 %y) {
1111+
; CHECK-LABEL: @or_xor_not_uses1(
1112+
; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[Y:%.*]], -1
1113+
; CHECK-NEXT: call void @use(i32 [[NOT]])
1114+
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
1115+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y]]
1116+
; CHECK-NEXT: ret i32 [[OR1]]
1117+
;
1118+
%not = xor i32 %y, -1
1119+
call void @use(i32 %not)
1120+
%xor = xor i32 %x, %not
1121+
%or1 = or i32 %xor, %y
1122+
ret i32 %or1
1123+
}
1124+
1125+
define i32 @or_xor_not_uses2(i32 %x, i32 %y) {
1126+
; CHECK-LABEL: @or_xor_not_uses2(
1127+
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1128+
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1
1129+
; CHECK-NEXT: call void @use(i32 [[XOR]])
1130+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XOR]], [[Y]]
1131+
; CHECK-NEXT: ret i32 [[OR1]]
1132+
;
1133+
%not = xor i32 %y, -1
1134+
%xor = xor i32 %x, %not
1135+
call void @use(i32 %xor)
1136+
%or1 = or i32 %xor, %y
1137+
ret i32 %or1
1138+
}
1139+
1140+
define i32 @or_xor_and_commuted1(i32 %x, i32 %y) {
1141+
; CHECK-LABEL: @or_xor_and_commuted1(
1142+
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
1143+
; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
1144+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[X_NOT]]
1145+
; CHECK-NEXT: ret i32 [[OR1]]
1146+
;
1147+
%yy = mul i32 %y, %y ; thwart complexity-based ordering
1148+
%not = xor i32 %yy, -1
1149+
%xor = xor i32 %not, %x
1150+
%or1 = or i32 %yy, %xor
1151+
ret i32 %or1
1152+
}
1153+
1154+
define i32 @or_xor_and_commuted2(i32 %x, i32 %y) {
1155+
; CHECK-LABEL: @or_xor_and_commuted2(
1156+
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
1157+
; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
1158+
; CHECK-NEXT: [[XX_NOT:%.*]] = xor i32 [[XX]], -1
1159+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[XX_NOT]]
1160+
; CHECK-NEXT: ret i32 [[OR1]]
1161+
;
1162+
%yy = mul i32 %y, %y ; thwart complexity-based ordering
1163+
%xx = mul i32 %x, %x ; thwart complexity-based ordering
1164+
%not = xor i32 %yy, -1
1165+
%xor = xor i32 %xx, %not
1166+
%or1 = or i32 %xor, %yy
1167+
ret i32 %or1
1168+
}

llvm/test/Transforms/InstCombine/or.ll

Lines changed: 116 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ define i32 @test40d(i32 %a, i32 %b) {
743743

744744
define i32 @test45(i32 %x, i32 %y, i32 %z) {
745745
; CHECK-LABEL: @test45(
746-
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
746+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Z:%.*]], [[X:%.*]]
747747
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
748748
; CHECK-NEXT: ret i32 [[OR1]]
749749
;
@@ -753,10 +753,40 @@ define i32 @test45(i32 %x, i32 %y, i32 %z) {
753753
ret i32 %or1
754754
}
755755

756+
define i32 @test45_uses1(i32 %x, i32 %y, i32 %z) {
757+
; CHECK-LABEL: @test45_uses1(
758+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]]
759+
; CHECK-NEXT: call void @use(i32 [[OR]])
760+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Z]], [[X:%.*]]
761+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y]]
762+
; CHECK-NEXT: ret i32 [[OR1]]
763+
;
764+
%or = or i32 %y, %z
765+
call void @use(i32 %or)
766+
%and = and i32 %x, %or
767+
%or1 = or i32 %and, %y
768+
ret i32 %or1
769+
}
770+
771+
define i32 @test45_uses2(i32 %x, i32 %y, i32 %z) {
772+
; CHECK-LABEL: @test45_uses2(
773+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]]
774+
; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR]], [[X:%.*]]
775+
; CHECK-NEXT: call void @use(i32 [[AND]])
776+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[Y]]
777+
; CHECK-NEXT: ret i32 [[OR1]]
778+
;
779+
%or = or i32 %y, %z
780+
%and = and i32 %x, %or
781+
call void @use(i32 %and)
782+
%or1 = or i32 %and, %y
783+
ret i32 %or1
784+
}
785+
756786
define i32 @test45_commuted1(i32 %x, i32 %y, i32 %z) {
757787
; CHECK-LABEL: @test45_commuted1(
758788
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
759-
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
789+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Z:%.*]], [[X:%.*]]
760790
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
761791
; CHECK-NEXT: ret i32 [[OR1]]
762792
;
@@ -772,7 +802,7 @@ define i32 @test45_commuted2(i32 %x, i32 %y, i32 %z) {
772802
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
773803
; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
774804
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[XX]], [[Z:%.*]]
775-
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
805+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[YY]]
776806
; CHECK-NEXT: ret i32 [[OR1]]
777807
;
778808
%yy = mul i32 %y, %y ; thwart complexity-based ordering
@@ -788,7 +818,7 @@ define i32 @test45_commuted3(i32 %x, i32 %y, i32 %z) {
788818
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
789819
; CHECK-NEXT: [[ZZ:%.*]] = mul i32 [[Z:%.*]], [[Z]]
790820
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZZ]], [[X:%.*]]
791-
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
821+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[YY]]
792822
; CHECK-NEXT: ret i32 [[OR1]]
793823
;
794824
%yy = mul i32 %y, %y ; thwart complexity-based ordering
@@ -1918,3 +1948,85 @@ define i32 @test_or_and_and_multiuse(i32 %a, i32 %b, i32 %c) {
19181948
%or = or i32 %and2, %a
19191949
ret i32 %or
19201950
}
1951+
1952+
define i32 @or_xor_and(i32 %x, i32 %y, i32 %z) {
1953+
; CHECK-LABEL: @or_xor_and(
1954+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
1955+
; CHECK-NEXT: ret i32 [[OR1]]
1956+
;
1957+
%and = and i32 %y, %z
1958+
%xor = xor i32 %x, %and
1959+
%or1 = or i32 %xor, %y
1960+
ret i32 %or1
1961+
}
1962+
1963+
define i32 @or_xor_and_uses1(i32 %x, i32 %y, i32 %z) {
1964+
; CHECK-LABEL: @or_xor_and_uses1(
1965+
; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]]
1966+
; CHECK-NEXT: call void @use(i32 [[AND]])
1967+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[Y]]
1968+
; CHECK-NEXT: ret i32 [[OR1]]
1969+
;
1970+
%and = and i32 %y, %z
1971+
call void @use(i32 %and)
1972+
%xor = xor i32 %x, %and
1973+
%or1 = or i32 %xor, %y
1974+
ret i32 %or1
1975+
}
1976+
1977+
define i32 @or_xor_and_uses2(i32 %x, i32 %y, i32 %z) {
1978+
; CHECK-LABEL: @or_xor_and_uses2(
1979+
; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]]
1980+
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[AND]], [[X:%.*]]
1981+
; CHECK-NEXT: call void @use(i32 [[XOR]])
1982+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X]], [[Y]]
1983+
; CHECK-NEXT: ret i32 [[OR1]]
1984+
;
1985+
%and = and i32 %y, %z
1986+
%xor = xor i32 %x, %and
1987+
call void @use(i32 %xor)
1988+
%or1 = or i32 %xor, %y
1989+
ret i32 %or1
1990+
}
1991+
1992+
define i32 @or_xor_and_commuted1(i32 %x, i32 %y, i32 %z) {
1993+
; CHECK-LABEL: @or_xor_and_commuted1(
1994+
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
1995+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[X:%.*]]
1996+
; CHECK-NEXT: ret i32 [[OR1]]
1997+
;
1998+
%yy = mul i32 %y, %y ; thwart complexity-based ordering
1999+
%and = and i32 %yy, %z
2000+
%xor = xor i32 %and, %x
2001+
%or1 = or i32 %yy, %xor
2002+
ret i32 %or1
2003+
}
2004+
2005+
define i32 @or_xor_and_commuted2(i32 %x, i32 %y, i32 %z) {
2006+
; CHECK-LABEL: @or_xor_and_commuted2(
2007+
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
2008+
; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
2009+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XX]], [[YY]]
2010+
; CHECK-NEXT: ret i32 [[OR1]]
2011+
;
2012+
%yy = mul i32 %y, %y ; thwart complexity-based ordering
2013+
%xx = mul i32 %x, %x ; thwart complexity-based ordering
2014+
%and = and i32 %yy, %z
2015+
%xor = xor i32 %xx, %and
2016+
%or1 = or i32 %xor, %yy
2017+
ret i32 %or1
2018+
}
2019+
2020+
define i32 @or_xor_and_commuted3(i32 %x, i32 %y, i32 %z) {
2021+
; CHECK-LABEL: @or_xor_and_commuted3(
2022+
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
2023+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[X:%.*]]
2024+
; CHECK-NEXT: ret i32 [[OR1]]
2025+
;
2026+
%yy = mul i32 %y, %y ; thwart complexity-based ordering
2027+
%zz = mul i32 %z, %z ; thwart complexity-based ordering
2028+
%and = and i32 %zz, %yy
2029+
%xor = xor i32 %and, %x
2030+
%or1 = or i32 %xor, %yy
2031+
ret i32 %or1
2032+
}

0 commit comments

Comments
 (0)