Skip to content

Commit 5916041

Browse files
committed
[InstSimpify] Simplifying (xor (sub C_Mask, X), C_Mask) -> X
Helps address regressions with folding `clz(Pow2)`. Proof: https://alive2.llvm.org/ce/z/zGwUBp
1 parent 62adb89 commit 5916041

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,14 @@ static Value *simplifySubInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
871871
if (Value *V = simplifyByDomEq(Instruction::Sub, Op0, Op1, Q, MaxRecurse))
872872
return V;
873873

874+
// (sub nuw C_Mask, (xor X, C_Mask)) -> X
875+
if (IsNUW) {
876+
Value *X;
877+
if (match(Op1, m_Xor(m_Value(X), m_Specific(Op0))) &&
878+
match(Op0, m_CheckedInt([](const APInt &C) { return C.isMask(); })))
879+
return X;
880+
}
881+
874882
return nullptr;
875883
}
876884

@@ -2540,6 +2548,14 @@ static Value *simplifyXorInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
25402548
if (Value *V = simplifyByDomEq(Instruction::Xor, Op0, Op1, Q, MaxRecurse))
25412549
return V;
25422550

2551+
// (xor (sub nuw C_Mask, X), C_Mask) -> X
2552+
{
2553+
Value *X;
2554+
if (match(Op0, m_NUWSub(m_Specific(Op1), m_Value(X))) &&
2555+
match(Op1, m_CheckedInt([](const APInt &C) { return C.isMask(); })))
2556+
return X;
2557+
}
2558+
25432559
return nullptr;
25442560
}
25452561

llvm/test/Transforms/InstSimplify/subnuw-with-xor.ll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ define i8 @xor_w_sub_fail_not_mask(i8 range(i8 0, 16) %x) {
5252
define i8 @xor_w_sub_okay(i8 range(i8 0, 16) %x) {
5353
; CHECK-LABEL: define i8 @xor_w_sub_okay(
5454
; CHECK-SAME: i8 range(i8 0, 16) [[X:%.*]]) {
55-
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], 31
56-
; CHECK-NEXT: [[R:%.*]] = sub nuw nsw i8 31, [[XOR]]
57-
; CHECK-NEXT: ret i8 [[R]]
55+
; CHECK-NEXT: ret i8 [[X]]
5856
;
5957
%xor = xor i8 %x, 31
6058
%r = sub nsw nuw i8 31, %xor
@@ -112,9 +110,7 @@ define i8 @sub_w_sub_fail_not_mask(i8 range(i8 0, 16) %x) {
112110
define i8 @sub_w_sub_okay(i8 range(i8 0, 16) %x) {
113111
; CHECK-LABEL: define i8 @sub_w_sub_okay(
114112
; CHECK-SAME: i8 range(i8 0, 16) [[X:%.*]]) {
115-
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i8 31, [[X]]
116-
; CHECK-NEXT: [[R:%.*]] = xor i8 [[SUB]], 31
117-
; CHECK-NEXT: ret i8 [[R]]
113+
; CHECK-NEXT: ret i8 [[X]]
118114
;
119115
%sub = sub nsw nuw i8 31, %x
120116
%r = xor i8 %sub, 31

0 commit comments

Comments
 (0)