Skip to content

Commit 43be1b8

Browse files
committed
[InstCombine] Fold shifts + selects with -1 to scmp(X, 0)
1 parent c84e7b2 commit 43be1b8

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4680,5 +4680,31 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
46804680
Align(MaskedLoadAlignment->getZExtValue()),
46814681
CondVal, FalseVal));
46824682

4683+
// Canonicalize sign function ashr pattern: select (icmp slt X, 1), ashr X,
4684+
// bitwidth-1, 1 -> scmp(X, 0)
4685+
// Also handles: select (icmp sgt X, 0), 1, ashr X, bitwidth-1 -> scmp(X, 0)
4686+
Value *X;
4687+
unsigned BitWidth = SI.getType()->getScalarSizeInBits();
4688+
CmpPredicate Pred;
4689+
Value *CmpLHS, *CmpRHS;
4690+
4691+
// Canonicalize sign function ashr patterns:
4692+
// select (icmp slt X, 1), ashr X, bitwidth-1, 1 -> scmp(X, 0)
4693+
// select (icmp sgt X, 0), 1, ashr X, bitwidth-1 -> scmp(X, 0)
4694+
if (match(&SI, m_Select(m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)),
4695+
m_Value(TrueVal), m_Value(FalseVal))) &&
4696+
((Pred == ICmpInst::ICMP_SLT && match(CmpLHS, m_Value(X)) &&
4697+
match(CmpRHS, m_One()) &&
4698+
match(TrueVal, m_AShr(m_Deferred(X), m_SpecificInt(BitWidth - 1))) &&
4699+
match(FalseVal, m_One())) ||
4700+
(Pred == ICmpInst::ICMP_SGT && match(CmpLHS, m_Value(X)) &&
4701+
match(CmpRHS, m_Zero()) && match(TrueVal, m_One()) &&
4702+
match(FalseVal, m_AShr(m_Deferred(X), m_SpecificInt(BitWidth - 1)))))) {
4703+
4704+
Function *Scmp = Intrinsic::getOrInsertDeclaration(
4705+
SI.getModule(), Intrinsic::scmp, {SI.getType(), SI.getType()});
4706+
return CallInst::Create(Scmp, {X, ConstantInt::get(SI.getType(), 0)});
4707+
}
4708+
46834709
return nullptr;
46844710
}

llvm/test/Transforms/InstCombine/scmp.ll

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -519,9 +519,7 @@ define <3 x i2> @scmp_unary_shuffle_ops(<3 x i8> %x, <3 x i8> %y) {
519519
define i32 @scmp_sgt_slt(i32 %a) {
520520
; CHECK-LABEL: define i32 @scmp_sgt_slt(
521521
; CHECK-SAME: i32 [[A:%.*]]) {
522-
; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr i32 [[A]], 31
523-
; CHECK-NEXT: [[CMP_INV:%.*]] = icmp slt i32 [[A]], 1
524-
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP_INV]], i32 [[A_LOBIT]], i32 1
522+
; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)
525523
; CHECK-NEXT: ret i32 [[RETVAL_0]]
526524
;
527525
%cmp = icmp sgt i32 %a, 0
@@ -751,9 +749,7 @@ define i8 @scmp_from_select_eq_and_gt_neg3(i32 %x, i32 %y) {
751749
define i32 @scmp_ashr(i32 %a) {
752750
; CHECK-LABEL: define i32 @scmp_ashr(
753751
; CHECK-SAME: i32 [[A:%.*]]) {
754-
; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr i32 [[A]], 31
755-
; CHECK-NEXT: [[CMP_INV:%.*]] = icmp slt i32 [[A]], 1
756-
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP_INV]], i32 [[A_LOBIT]], i32 1
752+
; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)
757753
; CHECK-NEXT: ret i32 [[RETVAL_0]]
758754
;
759755
%a.lobit = ashr i32 %a, 31
@@ -766,9 +762,7 @@ define i32 @scmp_ashr(i32 %a) {
766762
define i8 @scmp_ashr_sgt_pattern(i8 %a) {
767763
; CHECK-LABEL: define i8 @scmp_ashr_sgt_pattern(
768764
; CHECK-SAME: i8 [[A:%.*]]) {
769-
; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr i8 [[A]], 7
770-
; CHECK-NEXT: [[CMP_INV:%.*]] = icmp slt i8 [[A]], 1
771-
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP_INV]], i8 [[A_LOBIT]], i8 1
765+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i8(i8 [[A]], i8 0)
772766
; CHECK-NEXT: ret i8 [[R]]
773767
;
774768
%a.lobit = ashr i8 %a, 7
@@ -781,9 +775,7 @@ define i8 @scmp_ashr_sgt_pattern(i8 %a) {
781775
define i8 @scmp_ashr_slt_pattern(i8 %a) {
782776
; CHECK-LABEL: define i8 @scmp_ashr_slt_pattern(
783777
; CHECK-SAME: i8 [[A:%.*]]) {
784-
; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr i8 [[A]], 7
785-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A]], 1
786-
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP]], i8 [[A_LOBIT]], i8 1
778+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i8(i8 [[A]], i8 0)
787779
; CHECK-NEXT: ret i8 [[R]]
788780
;
789781
%a.lobit = ashr i8 %a, 7

0 commit comments

Comments
 (0)