Skip to content

Commit e484974

Browse files
committed
fixup! [InstCombine] Simplify and/or by replacing operands with constants
1 parent c8b3af5 commit e484974

File tree

5 files changed

+45
-40
lines changed

5 files changed

+45
-40
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,23 +2188,6 @@ static Value *simplifyAndOrWithOpReplaced(Value *X, Value *Y, bool IsAnd,
21882188
if (isa<Constant>(X) || X == Y)
21892189
return nullptr;
21902190

2191-
auto RecursivelyReplaceUses = [&](Instruction::BinaryOps Opcode, Value *Op0,
2192-
Value *Op1) -> Value * {
2193-
if (Depth == 2)
2194-
return nullptr;
2195-
2196-
// TODO: Relax the one-use constraint to clean up existing hard-coded
2197-
// simplifications.
2198-
if (!X->hasOneUse())
2199-
return nullptr;
2200-
Value *NewOp0 = simplifyAndOrWithOpReplaced(Op0, Y, IsAnd, IC, Depth + 1);
2201-
Value *NewOp1 = simplifyAndOrWithOpReplaced(Op1, Y, IsAnd, IC, Depth + 1);
2202-
if (!NewOp0 && !NewOp1)
2203-
return nullptr;
2204-
return IC.Builder.CreateBinOp(Opcode, NewOp0 ? NewOp0 : Op0,
2205-
NewOp1 ? NewOp1 : Op1);
2206-
};
2207-
22082191
Value *RHS;
22092192
if (match(X, m_c_And(m_Specific(Y), m_Value(RHS)))) {
22102193
return IsAnd ? RHS : Constant::getNullValue(X->getType());
@@ -2222,11 +2205,20 @@ static Value *simplifyAndOrWithOpReplaced(Value *X, Value *Y, bool IsAnd,
22222205
return RHS;
22232206
}
22242207

2225-
// FIXME: Is it correct to decompose xor if Y may be undef?
2208+
// Replace uses of Y in X recursively.
22262209
Value *Op0, *Op1;
2227-
if (match(X, m_BitwiseLogic(m_Value(Op0), m_Value(Op1))))
2228-
return RecursivelyReplaceUses(cast<BinaryOperator>(X)->getOpcode(), Op0,
2229-
Op1);
2210+
if (Depth < 2 && match(X, m_BitwiseLogic(m_Value(Op0), m_Value(Op1)))) {
2211+
// TODO: Relax the one-use constraint to clean up existing hard-coded
2212+
// simplifications.
2213+
if (!X->hasOneUse())
2214+
return nullptr;
2215+
Value *NewOp0 = simplifyAndOrWithOpReplaced(Op0, Y, IsAnd, IC, Depth + 1);
2216+
Value *NewOp1 = simplifyAndOrWithOpReplaced(Op1, Y, IsAnd, IC, Depth + 1);
2217+
if (!NewOp0 && !NewOp1)
2218+
return nullptr;
2219+
return IC.Builder.CreateBinOp(cast<BinaryOperator>(X)->getOpcode(),
2220+
NewOp0 ? NewOp0 : Op0, NewOp1 ? NewOp1 : Op1);
2221+
}
22302222
return nullptr;
22312223
}
22322224

@@ -2753,7 +2745,7 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
27532745
return Res;
27542746

27552747
if (Value *V = simplifyAndOrWithOpReplaced(Op0, Op1, /*IsAnd*/ true, *this))
2756-
return BinaryOperator::CreateAnd(Op1, V);
2748+
return BinaryOperator::CreateAnd(V, Op1);
27572749
if (Value *V = simplifyAndOrWithOpReplaced(Op1, Op0, /*IsAnd*/ true, *this))
27582750
return BinaryOperator::CreateAnd(Op0, V);
27592751

@@ -3957,7 +3949,7 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
39573949
return Res;
39583950

39593951
if (Value *V = simplifyAndOrWithOpReplaced(Op0, Op1, /*IsAnd*/ false, *this))
3960-
return BinaryOperator::CreateOr(Op1, V);
3952+
return BinaryOperator::CreateOr(V, Op1);
39613953
if (Value *V = simplifyAndOrWithOpReplaced(Op1, Op0, /*IsAnd*/ false, *this))
39623954
return BinaryOperator::CreateOr(Op0, V);
39633955

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ define void @simplify_before_foldAndOfICmps(ptr %p) {
370370
; CHECK-NEXT: [[B11:%.*]] = zext i1 [[TMP1]] to i16
371371
; CHECK-NEXT: [[C10:%.*]] = icmp ugt i16 [[L7]], [[B11]]
372372
; CHECK-NEXT: [[C7:%.*]] = icmp slt i16 [[L7]], 0
373-
; CHECK-NEXT: [[C3:%.*]] = and i1 [[C10]], [[C7]]
373+
; CHECK-NEXT: [[C3:%.*]] = and i1 [[C7]], [[C10]]
374374
; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[C10]], true
375375
; CHECK-NEXT: [[C18:%.*]] = or i1 [[C7]], [[TMP2]]
376376
; CHECK-NEXT: [[TMP3:%.*]] = sext i1 [[C3]] to i64

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ define i32 @and_xor_not_common_op_extrause(i32 %a, i32 %b, ptr %dst) {
113113
; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], ptr [[DST:%.*]]) {
114114
; CHECK-NEXT: [[B2:%.*]] = xor i32 [[B]], -1
115115
; CHECK-NEXT: store i32 [[B2]], ptr [[DST]], align 4
116-
; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[B]]
116+
; CHECK-NEXT: [[T4:%.*]] = and i32 [[B]], [[A]]
117117
; CHECK-NEXT: ret i32 [[T4]]
118118
;
119119
%b2 = xor i32 %b, -1

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ define i16 @test5_extra_use_not_xor(i16 %x, i16 %y, ptr %dst_not, ptr %dst_xor)
156156

157157
define i8 @xor_common_op_commute0(i8 %x, i8 %y) {
158158
; CHECK-LABEL: @xor_common_op_commute0(
159-
; CHECK-NEXT: [[Z:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
159+
; CHECK-NEXT: [[Z:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
160160
; CHECK-NEXT: ret i8 [[Z]]
161161
;
162162
%xor = xor i8 %x, %y
@@ -168,7 +168,7 @@ define i8 @xor_common_op_commute1(i8 %x, i8 %y) {
168168
; CHECK-LABEL: @xor_common_op_commute1(
169169
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]
170170
; CHECK-NEXT: call void @use(i8 [[XOR]])
171-
; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[Y]]
171+
; CHECK-NEXT: [[Z:%.*]] = or i8 [[Y]], [[X]]
172172
; CHECK-NEXT: ret i8 [[Z]]
173173
;
174174
%xor = xor i8 %y, %x
@@ -1059,7 +1059,7 @@ define i8 @or_nand_xor_common_op_commute3_use3(i8 %x, i8 %y, i8 %z) {
10591059
; (a ^ 4) & (a ^ ~4) -> -1
10601060
define i32 @PR75692_1(i32 %x) {
10611061
; CHECK-LABEL: @PR75692_1(
1062-
; CHECK-NEXT: ret i32 -1
1062+
; CHECK-NEXT: ret i32 -1
10631063
;
10641064
%t2 = xor i32 %x, 4
10651065
%t3 = xor i32 %x, -5
@@ -1069,11 +1069,11 @@ define i32 @PR75692_1(i32 %x) {
10691069

10701070
; (a ^ 4) & (a ^ 3) is not -1
10711071
define i32 @PR75692_2(i32 %x) {
1072-
; CHECK-LABEL: @PR75692_2
1073-
; CHECK-NEXT: %t2 = xor i32 %x, 4
1074-
; CHECK-NEXT: %t3 = xor i32 %x, -4
1075-
; CHECK-NEXT: %t4 = or i32 %t2, %t3
1076-
; CHECK-NEXT: ret i32 %t4
1072+
; CHECK-LABEL: @PR75692_2(
1073+
; CHECK-NEXT: [[T2:%.*]] = xor i32 [[X:%.*]], 4
1074+
; CHECK-NEXT: [[T3:%.*]] = xor i32 [[X]], -4
1075+
; CHECK-NEXT: [[T4:%.*]] = or i32 [[T2]], [[T3]]
1076+
; CHECK-NEXT: ret i32 [[T4]]
10771077
;
10781078
%t2 = xor i32 %x, 4
10791079
%t3 = xor i32 %x, -4
@@ -1083,11 +1083,11 @@ define i32 @PR75692_2(i32 %x) {
10831083

10841084
; (a ^ 4) & (b ^ ~4) is not -1, since a != b is possible
10851085
define i32 @PR75692_3(i32 %x, i32 %y) {
1086-
; CHECK-LABEL: @PR75692_3
1087-
; CHECK-NEXT: %t2 = xor i32 %x, 4
1088-
; CHECK-NEXT: %t3 = xor i32 %y, -5
1089-
; CHECK-NEXT: %t4 = or i32 %t2, %t3
1090-
; CHECK-NEXT: ret i32 %t4
1086+
; CHECK-LABEL: @PR75692_3(
1087+
; CHECK-NEXT: [[T2:%.*]] = xor i32 [[X:%.*]], 4
1088+
; CHECK-NEXT: [[T3:%.*]] = xor i32 [[Y:%.*]], -5
1089+
; CHECK-NEXT: [[T4:%.*]] = or i32 [[T2]], [[T3]]
1090+
; CHECK-NEXT: ret i32 [[T4]]
10911091
;
10921092
%t2 = xor i32 %x, 4
10931093
%t3 = xor i32 %y, -5

llvm/test/Transforms/InstCombine/or.ll

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,8 +1781,8 @@ if.else:
17811781
; Tests from PR76554
17821782
define i32 @test_or_and_xor_constant(i32 %x, i32 %y) {
17831783
; CHECK-LABEL: @test_or_and_xor_constant(
1784-
; CHECK-NEXT: [[A1:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
1785-
; CHECK-NEXT: [[D:%.*]] = and i32 [[A1]], -2147483648
1784+
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1785+
; CHECK-NEXT: [[D:%.*]] = and i32 [[TMP1]], -2147483648
17861786
; CHECK-NEXT: ret i32 [[D]]
17871787
;
17881788
%a = and i32 %x, -2147483648
@@ -1888,3 +1888,16 @@ define i32 @test_or_and_xor_multiuse2(i32 %a, i32 %b, i32 %c) {
18881888
%or = or i32 %and, %a
18891889
ret i32 %or
18901890
}
1891+
1892+
define i32 @test_or_add_xor(i32 %a, i32 %b, i32 %c) {
1893+
; CHECK-LABEL: @test_or_add_xor(
1894+
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
1895+
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[XOR]], [[C:%.*]]
1896+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[ADD]], [[A]]
1897+
; CHECK-NEXT: ret i32 [[OR]]
1898+
;
1899+
%xor = xor i32 %a, %b
1900+
%add = add i32 %xor, %c
1901+
%or = or i32 %add, %a
1902+
ret i32 %or
1903+
}

0 commit comments

Comments
 (0)