[llvm] [InstCombine] Add fold combining adjacent extracted bit fields to restore optimization for separate truncations (PR #219598)
Ryunosuke Yanashita via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 08:06:24 PDT 2026
https://github.com/ryanashita updated https://github.com/llvm/llvm-project/pull/219598
>From 213916f7b27479c213ccf824d30f7a6e75ad97d5 Mon Sep 17 00:00:00 2001
From: ryanashita <ryunosukeyanashita at gmail.com>
Date: Fri, 28 Aug 2026 16:10:47 -0700
Subject: [PATCH 1/7] [InstCombine] Add fold combining adjacent extracted bit
fields
---
.../InstCombine/InstCombineAndOrXor.cpp | 23 +++++++++++
llvm/test/Transforms/InstCombine/trunc.ll | 38 +++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 9e9ebfe5c5e90..43a4d161f11d9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4319,6 +4319,29 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
return BinaryOperator::CreateAnd(Or, C01);
}
}
+
+ // (trunc (lshr X, S) & C0) | (lshr (trunc X), S & C1)
+ // --> (trunc (lshr X, S) & (C0 | C1) (and similar cases)
+ // A = trunc (lshr X, S) B = lshr (trunc X), S
+ const APInt *ShiftAmt;
+ if (match(A, m_OneUse(m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt))))) &&
+ match(B, m_LShr(m_Trunc(m_Specific(X)),
+ m_SpecificInt(ShiftAmt->getZExtValue())))) {
+ APInt CombinedMask = *C0 | *C1;
+ return BinaryOperator::CreateAnd(
+ A, ConstantInt::get(I.getType(), CombinedMask));
+ }
+ // A = lshr (trunc X), S
+ // B = trunc (lshr X, S)
+ const APInt *ReverseShiftAmt;
+ if (match(B, m_OneUse(m_Trunc(
+ m_LShr(m_Value(X), m_APInt(ReverseShiftAmt))))) &&
+ match(A, m_LShr(m_Trunc(m_Specific(X)),
+ m_SpecificInt(ReverseShiftAmt->getZExtValue())))) {
+ APInt CombinedMask = *C0 | *C1;
+ return BinaryOperator::CreateAnd(
+ B, ConstantInt::get(I.getType(), CombinedMask));
+ }
}
// Don't try to form a select if it's unlikely that we'll get rid of at
diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll
index 507a4678a7a1f..cd914ce886773 100644
--- a/llvm/test/Transforms/InstCombine/trunc.ll
+++ b/llvm/test/Transforms/InstCombine/trunc.ll
@@ -1462,3 +1462,41 @@ define i1 @neg_trunc_nuw_lshr(i8 %x, i8 %c) {
%ret = trunc nuw i8 %lshr to i1
ret i1 %ret
}
+
+define i32 @separate_truncs_i32(i64 %x) {
+; CHECK-LABEL: @separate_truncs_i32(
+; CHECK-NEXT: %[[SHIFT:.*]] = lshr i64 %x, 16
+; CHECK-NEXT: %[[TRUNC:.*]] = trunc i64 %[[SHIFT]] to i32
+; CHECK-NEXT: %[[MASK:.*]] = and i32 %[[TRUNC]], 130816
+; CHECK-NEXT: ret i32 %[[MASK]]
+;
+ %wide.shift = lshr i64 %x, 16
+ %wide = trunc i64 %wide.shift to i32
+ %field.hi = and i32 %wide, 65536
+
+ %x.narrow = trunc i64 %x to i32
+ %narrow.shift = lshr i32 %x.narrow, 16
+ %field.lo = and i32 %narrow.shift, 65280
+
+ %result = or i32 %field.hi, %field.lo
+ ret i32 %result
+}
+
+define i32 @separate_truncs_i32_reverse(i64 %x) {
+; CHECK-LABEL: @separate_truncs_i32_reverse(
+; CHECK-NEXT: %[[SHIFT:.*]] = lshr i64 %x, 16
+; CHECK-NEXT: %[[TRUNC:.*]] = trunc i64 %[[SHIFT]] to i32
+; CHECK-NEXT: %[[MASK:.*]] = and i32 %[[TRUNC]], 130816
+; CHECK-NEXT: ret i32 %[[MASK]]
+;
+ %x.narrow = trunc i64 %x to i32
+ %narrow.shift = lshr i32 %x.narrow, 16
+ %field.lo = and i32 %narrow.shift, 65280
+
+ %wide.shift = lshr i64 %x, 16
+ %wide = trunc i64 %wide.shift to i32
+ %field.hi = and i32 %wide, 65536
+
+ %result = or i32 %field.lo, %field.hi
+ ret i32 %result
+}
\ No newline at end of file
>From f1ca6b1d7fea1413ed2c3a74f85db37e36f5c612 Mon Sep 17 00:00:00 2001
From: ryanashita <ryunosukeyanashita at gmail.com>
Date: Tue, 1 Sep 2026 14:59:16 -0700
Subject: [PATCH 2/7] Address comments and make changes
---
.../InstCombine/InstCombineAndOrXor.cpp | 35 ++++++++++---------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 43a4d161f11d9..b5de5b2b9100c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4321,27 +4321,28 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
}
// (trunc (lshr X, S) & C0) | (lshr (trunc X), S & C1)
- // --> (trunc (lshr X, S) & (C0 | C1) (and similar cases)
+ // --> (trunc (lshr X, S) & (C0 | C1) (and similar cases)
// A = trunc (lshr X, S) B = lshr (trunc X), S
const APInt *ShiftAmt;
- if (match(A, m_OneUse(m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt))))) &&
- match(B, m_LShr(m_Trunc(m_Specific(X)),
- m_SpecificInt(ShiftAmt->getZExtValue())))) {
- APInt CombinedMask = *C0 | *C1;
- return BinaryOperator::CreateAnd(
- A, ConstantInt::get(I.getType(), CombinedMask));
+ Value *Wide, *Narrow;
+ if (match(A, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt))))) {
+ Wide = A;
+ Narrow = B;
+ } else if (match(B, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt))))) {
+ Wide = B;
+ Narrow = A;
+ } else {
+ return nullptr;
}
- // A = lshr (trunc X), S
- // B = trunc (lshr X, S)
- const APInt *ReverseShiftAmt;
- if (match(B, m_OneUse(m_Trunc(
- m_LShr(m_Value(X), m_APInt(ReverseShiftAmt))))) &&
- match(A, m_LShr(m_Trunc(m_Specific(X)),
- m_SpecificInt(ReverseShiftAmt->getZExtValue())))) {
- APInt CombinedMask = *C0 | *C1;
- return BinaryOperator::CreateAnd(
- B, ConstantInt::get(I.getType(), CombinedMask));
+
+ if (!match(Narrow,
+ m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt)))) {
+ return nullptr;
}
+
+ APInt CombinedMask = *C0 | *C1;
+ return BinaryOperator::CreateAnd(
+ Wide, ConstantInt::get(I.getType(), CombinedMask));
}
// Don't try to form a select if it's unlikely that we'll get rid of at
>From d60678aa354ec0c47551f2f1c6a7fa87dc3d11bc Mon Sep 17 00:00:00 2001
From: ryanashita <ryunosukeyanashita at gmail.com>
Date: Sun, 6 Sep 2026 11:19:59 -0700
Subject: [PATCH 3/7] Add multiuse tests and address comments
---
.../InstCombine/InstCombineAndOrXor.cpp | 27 +++++------
llvm/test/Transforms/InstCombine/trunc.ll | 45 ++++++++++++++++++-
2 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index b5de5b2b9100c..7c2d8af727dae 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4324,25 +4324,18 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
// --> (trunc (lshr X, S) & (C0 | C1) (and similar cases)
// A = trunc (lshr X, S) B = lshr (trunc X), S
const APInt *ShiftAmt;
- Value *Wide, *Narrow;
- if (match(A, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt))))) {
- Wide = A;
- Narrow = B;
- } else if (match(B, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt))))) {
- Wide = B;
- Narrow = A;
- } else {
- return nullptr;
+ if (match(A, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt)))) &&
+ match(B, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt)))) {
+ return BinaryOperator::CreateAnd(
+ A, ConstantInt::get(I.getType(), *C0 | *C1));
}
-
- if (!match(Narrow,
- m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt)))) {
- return nullptr;
+ // A = lshr (trunc X), S
+ // B = trunc (lshr X, S)
+ if (match(B, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt)))) &&
+ match(A, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt)))) {
+ return BinaryOperator::CreateAnd(
+ B, ConstantInt::get(I.getType(), *C0 | *C1));
}
-
- APInt CombinedMask = *C0 | *C1;
- return BinaryOperator::CreateAnd(
- Wide, ConstantInt::get(I.getType(), CombinedMask));
}
// Don't try to form a select if it's unlikely that we'll get rid of at
diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll
index cd914ce886773..d64b2626f8af6 100644
--- a/llvm/test/Transforms/InstCombine/trunc.ll
+++ b/llvm/test/Transforms/InstCombine/trunc.ll
@@ -1499,4 +1499,47 @@ define i32 @separate_truncs_i32_reverse(i64 %x) {
%result = or i32 %field.lo, %field.hi
ret i32 %result
-}
\ No newline at end of file
+}
+
+define i32 @separate_truncs_i32_multiuse(i64 %x) {
+; CHECK-LABEL: @separate_truncs_i32_multiuse(
+; CHECK-NEXT: %[[SHIFT:.*]] = lshr i64 %x, 16
+; CHECK-NEXT: %[[TRUNC:.*]] = trunc i64 %[[SHIFT]] to i32
+; CHECK-NEXT: call void @use(i32 %[[TRUNC]])
+; CHECK-NEXT: %[[MASK:.*]] = and i32 %[[TRUNC]], 130816
+; CHECK-NEXT: ret i32 %[[MASK]]
+;
+ %wide.shift = lshr i64 %x, 16
+ %wide = trunc i64 %wide.shift to i32
+ call void @use(i32 %wide)
+ %field.hi = and i32 %wide, 65536
+
+ %x.narrow = trunc i64 %x to i32
+ %narrow.shift = lshr i32 %x.narrow, 16
+ %field.lo = and i32 %narrow.shift, 65280
+
+ %result = or i32 %field.hi, %field.lo
+ ret i32 %result
+}
+
+define i32 @separate_truncs_i32_reverse_multiuse(i64 %x) {
+; CHECK-LABEL: @separate_truncs_i32_reverse_multiuse(
+; CHECK-NEXT: %[[NARROW:.*]] = trunc i64 %x to i32
+; CHECK-NEXT: call void @use(i32 %[[NARROW]])
+; CHECK-NEXT: %[[SHIFT:.*]] = lshr i64 %x, 16
+; CHECK-NEXT: %[[TRUNC:.*]] = trunc i64 %[[SHIFT]] to i32
+; CHECK-NEXT: %[[MASK:.*]] = and i32 %[[TRUNC]], 130816
+; CHECK-NEXT: ret i32 %[[MASK]]
+;
+ %x.narrow = trunc i64 %x to i32
+ call void @use(i32 %x.narrow)
+ %narrow.shift = lshr i32 %x.narrow, 16
+ %field.lo = and i32 %narrow.shift, 65280
+
+ %wide.shift = lshr i64 %x, 16
+ %wide = trunc i64 %wide.shift to i32
+ %field.hi = and i32 %wide, 65536
+
+ %result = or i32 %field.lo, %field.hi
+ ret i32 %result
+}
>From e47282d396837d8a384ddc8eb5527be7c2f5301e Mon Sep 17 00:00:00 2001
From: ryanashita <ryunosukeyanashita at gmail.com>
Date: Sun, 6 Sep 2026 11:23:16 -0700
Subject: [PATCH 4/7] added newline to trunc.ll test file
---
llvm/test/Transforms/InstCombine/trunc.ll | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll
index d64b2626f8af6..3cd84e9045bb3 100644
--- a/llvm/test/Transforms/InstCombine/trunc.ll
+++ b/llvm/test/Transforms/InstCombine/trunc.ll
@@ -1543,3 +1543,4 @@ define i32 @separate_truncs_i32_reverse_multiuse(i64 %x) {
%result = or i32 %field.lo, %field.hi
ret i32 %result
}
+
>From ff1185b791f1539976dd34c46aeccef1b2f55ed0 Mon Sep 17 00:00:00 2001
From: ryanashita <ryunosukeyanashita at gmail.com>
Date: Tue, 8 Sep 2026 16:58:47 -0700
Subject: [PATCH 5/7] add checks for shift amount and mask
---
.../lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 7c2d8af727dae..e86758b4a2a49 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4325,14 +4325,20 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
// A = trunc (lshr X, S) B = lshr (trunc X), S
const APInt *ShiftAmt;
if (match(A, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt)))) &&
- match(B, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt)))) {
+ match(B, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt))) &&
+ ShiftAmt->ult(A->getType()->getIntegerBitWidth()) &&
+ !C1->intersects(APInt::getHighBitsSet(
+ A->getType()->getIntegerBitWidth(), ShiftAmt->getZExtValue()))) {
return BinaryOperator::CreateAnd(
A, ConstantInt::get(I.getType(), *C0 | *C1));
}
// A = lshr (trunc X), S
// B = trunc (lshr X, S)
if (match(B, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt)))) &&
- match(A, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt)))) {
+ match(A, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt))) &&
+ ShiftAmt->ult(A->getType()->getIntegerBitWidth()) &&
+ !C0->intersects(APInt::getHighBitsSet(
+ A->getType()->getIntegerBitWidth(), ShiftAmt->getZExtValue()))) {
return BinaryOperator::CreateAnd(
B, ConstantInt::get(I.getType(), *C0 | *C1));
}
>From bc8a17b2f52199cfd470a1ca02c0899ef9feadac Mon Sep 17 00:00:00 2001
From: ryanashita <ryunosukeyanashita at gmail.com>
Date: Thu, 10 Sep 2026 11:30:33 -0700
Subject: [PATCH 6/7] Added negative tests and vector test
---
.../InstCombine/InstCombineAndOrXor.cpp | 12 ++---
llvm/test/Transforms/InstCombine/trunc.ll | 54 +++++++++++++++++++
2 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index e86758b4a2a49..b43720e078275 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4326,21 +4326,21 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
const APInt *ShiftAmt;
if (match(A, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt)))) &&
match(B, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt))) &&
- ShiftAmt->ult(A->getType()->getIntegerBitWidth()) &&
+ ShiftAmt->ult(A->getType()->getScalarSizeInBits()) &&
!C1->intersects(APInt::getHighBitsSet(
- A->getType()->getIntegerBitWidth(), ShiftAmt->getZExtValue()))) {
+ A->getType()->getScalarSizeInBits(), ShiftAmt->getZExtValue()))) {
return BinaryOperator::CreateAnd(
- A, ConstantInt::get(I.getType(), *C0 | *C1));
+ A, ConstantInt::getIntegerValue(I.getType(), *C0 | *C1));
}
// A = lshr (trunc X), S
// B = trunc (lshr X, S)
if (match(B, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt)))) &&
match(A, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt))) &&
- ShiftAmt->ult(A->getType()->getIntegerBitWidth()) &&
+ ShiftAmt->ult(A->getType()->getScalarSizeInBits()) &&
!C0->intersects(APInt::getHighBitsSet(
- A->getType()->getIntegerBitWidth(), ShiftAmt->getZExtValue()))) {
+ A->getType()->getScalarSizeInBits(), ShiftAmt->getZExtValue()))) {
return BinaryOperator::CreateAnd(
- B, ConstantInt::get(I.getType(), *C0 | *C1));
+ B, ConstantInt::getIntegerValue(I.getType(), *C0 | *C1));
}
}
diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll
index 3cd84e9045bb3..bdcb59052b2ba 100644
--- a/llvm/test/Transforms/InstCombine/trunc.ll
+++ b/llvm/test/Transforms/InstCombine/trunc.ll
@@ -1544,3 +1544,57 @@ define i32 @separate_truncs_i32_reverse_multiuse(i64 %x) {
ret i32 %result
}
+define <2 x i32> @separate_truncs_i32_reverse_vec(<2 x i64> %x) {
+; CHECK-LABEL: @separate_truncs_i32_reverse_vec(
+; CHECK-NEXT: %[[SHIFT:.*]] = lshr <2 x i64> %x, splat (i64 16)
+; CHECK-NEXT: %[[TRUNC:.*]] = trunc <2 x i64> %[[SHIFT]] to <2 x i32>
+; CHECK-NEXT: %[[MASK:.*]] = and <2 x i32> %[[TRUNC]], splat (i32 130816)
+; CHECK-NEXT: ret <2 x i32> %[[MASK]]
+;
+ %x.narrow = trunc <2 x i64> %x to <2 x i32>
+ %narrow.shift = lshr <2 x i32> %x.narrow, <i32 16, i32 16>
+ %field.lo = and <2 x i32> %narrow.shift, <i32 65280, i32 65280>
+
+ %wide.shift = lshr <2 x i64> %x, <i64 16, i64 16>
+ %wide = trunc <2 x i64> %wide.shift to <2 x i32>
+ %field.hi = and <2 x i32> %wide, <i32 65536, i32 65536>
+
+ %result = or <2 x i32> %field.lo, %field.hi
+ ret <2 x i32> %result
+}
+
+define i32 @neg_separate_truncs_i32_shift_geq_32(i64 %x) {
+; CHECK-LABEL: @neg_separate_truncs_i32_shift_geq_32(
+; CHECK-NEXT: ret i32 poison
+;
+ %wide.shift = lshr i64 %x, 32
+ %wide = trunc i64 %wide.shift to i32
+ %field.hi = and i32 %wide, 65536
+
+ %x.narrow = trunc i64 %x to i32
+ %narrow.shift = lshr i32 %x.narrow, 32
+ %field.lo = and i32 %narrow.shift, 65280
+
+ %result = or i32 %field.hi, %field.lo
+ ret i32 %result
+}
+
+; negative test: narrow mask 131072
+define i32 @neg_separate_truncs_i32_upper_bits(i64 %x) {
+; CHECK-LABEL: @neg_separate_truncs_i32_upper_bits(
+; CHECK-NEXT: %[[SHIFT:.*]] = lshr i64 %x, 16
+; CHECK-NEXT: %[[TRUNC:.*]] = trunc i64 %[[SHIFT]] to i32
+; CHECK-NEXT: %[[MASK:.*]] = and i32 %[[TRUNC]], 65536
+; CHECK-NEXT: ret i32 %[[MASK]]
+;
+ %wide.shift = lshr i64 %x, 16
+ %wide = trunc i64 %wide.shift to i32
+ %field.hi = and i32 %wide, 65536
+
+ %x.narrow = trunc i64 %x to i32
+ %narrow.shift = lshr i32 %x.narrow, 16
+ %field.lo = and i32 %narrow.shift, 131072
+
+ %result = or i32 %field.hi, %field.lo
+ ret i32 %result
+}
>From e292a5b0deac959e77dac8cd24d9ded954dbcd19 Mon Sep 17 00:00:00 2001
From: ryanashita <ryunosukeyanashita at gmail.com>
Date: Sun, 13 Sep 2026 08:05:51 -0700
Subject: [PATCH 7/7] address comments from dtcxzyw
---
.../Transforms/InstCombine/InstCombineAndOrXor.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index b43720e078275..eecd00621b8f1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4320,27 +4320,27 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
}
}
- // (trunc (lshr X, S) & C0) | (lshr (trunc X), S & C1)
- // --> (trunc (lshr X, S) & (C0 | C1) (and similar cases)
+ // ((trunc (lshr X, S)) & C0) | ((lshr (trunc X), S) & C1)
+ // --> (trunc (lshr X, S) & (C0 | C1)) (and similar cases)
// A = trunc (lshr X, S) B = lshr (trunc X), S
const APInt *ShiftAmt;
if (match(A, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt)))) &&
match(B, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt))) &&
- ShiftAmt->ult(A->getType()->getScalarSizeInBits()) &&
+ ShiftAmt->isIntN(A->getType()->getScalarSizeInBits()) &&
!C1->intersects(APInt::getHighBitsSet(
A->getType()->getScalarSizeInBits(), ShiftAmt->getZExtValue()))) {
return BinaryOperator::CreateAnd(
- A, ConstantInt::getIntegerValue(I.getType(), *C0 | *C1));
+ A, ConstantInt::get(I.getType(), *C0 | *C1));
}
// A = lshr (trunc X), S
// B = trunc (lshr X, S)
if (match(B, m_Trunc(m_LShr(m_Value(X), m_APInt(ShiftAmt)))) &&
match(A, m_LShr(m_Trunc(m_Specific(X)), m_SpecificInt(*ShiftAmt))) &&
- ShiftAmt->ult(A->getType()->getScalarSizeInBits()) &&
+ ShiftAmt->isIntN(A->getType()->getScalarSizeInBits()) &&
!C0->intersects(APInt::getHighBitsSet(
A->getType()->getScalarSizeInBits(), ShiftAmt->getZExtValue()))) {
return BinaryOperator::CreateAnd(
- B, ConstantInt::getIntegerValue(I.getType(), *C0 | *C1));
+ B, ConstantInt::get(I.getType(), *C0 | *C1));
}
}
More information about the llvm-commits
mailing list