[llvm] 79bb915 - [InstCombine] enhance fold for subtract-from-constant -> xor
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 8 07:11:30 PDT 2022
Author: Sanjay Patel
Date: 2022-07-08T10:02:19-04:00
New Revision: 79bb915fb60b2cd220d89e3bb54f67abb8cdb7bd
URL: https://github.com/llvm/llvm-project/commit/79bb915fb60b2cd220d89e3bb54f67abb8cdb7bd
DIFF: https://github.com/llvm/llvm-project/commit/79bb915fb60b2cd220d89e3bb54f67abb8cdb7bd.diff
LOG: [InstCombine] enhance fold for subtract-from-constant -> xor
A low-bit mask is not required:
https://alive2.llvm.org/ce/z/yPShss
This matches the SDAG implementation that was updated at:
8b756713140f
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/test/Transforms/InstCombine/sub-xor.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index f53cce10f61e5..01821a71be4d2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1965,14 +1965,12 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2));
}
+ // If there's no chance any bit will need to borrow from an adjacent bit:
+ // sub C, X --> xor X, C
const APInt *Op0C;
- if (match(Op0, m_APInt(Op0C)) && Op0C->isMask()) {
- // Turn this into a xor if LHS is 2^n-1 and the remaining bits are known
- // zero.
- KnownBits RHSKnown = computeKnownBits(Op1, 0, &I);
- if ((*Op0C | RHSKnown.Zero).isAllOnes())
- return BinaryOperator::CreateXor(Op1, Op0);
- }
+ if (match(Op0, m_APInt(Op0C)) &&
+ (~computeKnownBits(Op1, 0, &I).Zero).isSubsetOf(*Op0C))
+ return BinaryOperator::CreateXor(Op1, Op0);
{
Value *Y;
diff --git a/llvm/test/Transforms/InstCombine/sub-xor.ll b/llvm/test/Transforms/InstCombine/sub-xor.ll
index 388fa920b0cf6..f47bc2fdae7e9 100644
--- a/llvm/test/Transforms/InstCombine/sub-xor.ll
+++ b/llvm/test/Transforms/InstCombine/sub-xor.ll
@@ -28,7 +28,7 @@ define <2 x i32> @test1vec(<2 x i32> %x) {
define i8 @masked_sub_i8(i8 %x) {
; CHECK-LABEL: @masked_sub_i8(
; CHECK-NEXT: [[A:%.*]] = and i8 [[X:%.*]], 10
-; CHECK-NEXT: [[M:%.*]] = sub nuw nsw i8 11, [[A]]
+; CHECK-NEXT: [[M:%.*]] = xor i8 [[A]], 11
; CHECK-NEXT: ret i8 [[M]]
;
%a = and i8 %x, 10 ; 0b00001010
@@ -39,7 +39,7 @@ define i8 @masked_sub_i8(i8 %x) {
define <2 x i5> @masked_sub_v2i5(<2 x i5> %x) {
; CHECK-LABEL: @masked_sub_v2i5(
; CHECK-NEXT: [[A:%.*]] = and <2 x i5> [[X:%.*]], <i5 -8, i5 -8>
-; CHECK-NEXT: [[M:%.*]] = sub nuw nsw <2 x i5> <i5 -6, i5 -6>, [[A]]
+; CHECK-NEXT: [[M:%.*]] = xor <2 x i5> [[A]], <i5 -6, i5 -6>
; CHECK-NEXT: ret <2 x i5> [[M]]
;
%a = and <2 x i5> %x, <i5 24, i5 24> ; 0b11000
@@ -47,6 +47,8 @@ define <2 x i5> @masked_sub_v2i5(<2 x i5> %x) {
ret <2 x i5> %m
}
+; negative test - sub constant isn't superset of masked bits
+
define i8 @not_masked_sub_i8(i8 %x) {
; CHECK-LABEL: @not_masked_sub_i8(
; CHECK-NEXT: [[A:%.*]] = and i8 [[X:%.*]], 7
More information about the llvm-commits
mailing list