Skip to content

Commit 70205d0

Browse files
AZero13dvbuka
authored andcommitted
[InstCombine] Fold shifts + selects with -1 to scmp(X, 0) (llvm#164129)
This is because the sign function with 0 tends to be folded to ashr and other things. Alive2: https://alive2.llvm.org/ce/z/Q59KvH
1 parent 2480771 commit 70205d0

File tree

2 files changed

+79
-3
lines changed

2 files changed

+79
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4697,5 +4697,31 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
46974697
cast<IntrinsicInst>(TrueVal)->getParamAlign(0).valueOrOne(),
46984698
CondVal, FalseVal));
46994699

4700+
// Canonicalize sign function ashr pattern: select (icmp slt X, 1), ashr X,
4701+
// bitwidth-1, 1 -> scmp(X, 0)
4702+
// Also handles: select (icmp sgt X, 0), 1, ashr X, bitwidth-1 -> scmp(X, 0)
4703+
unsigned BitWidth = SI.getType()->getScalarSizeInBits();
4704+
CmpPredicate Pred;
4705+
Value *CmpLHS, *CmpRHS;
4706+
4707+
// Canonicalize sign function ashr patterns:
4708+
// select (icmp slt X, 1), ashr X, bitwidth-1, 1 -> scmp(X, 0)
4709+
// select (icmp sgt X, 0), 1, ashr X, bitwidth-1 -> scmp(X, 0)
4710+
if (match(&SI, m_Select(m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)),
4711+
m_Value(TrueVal), m_Value(FalseVal))) &&
4712+
((Pred == ICmpInst::ICMP_SLT && match(CmpRHS, m_One()) &&
4713+
match(TrueVal,
4714+
m_AShr(m_Specific(CmpLHS), m_SpecificInt(BitWidth - 1))) &&
4715+
match(FalseVal, m_One())) ||
4716+
(Pred == ICmpInst::ICMP_SGT && match(CmpRHS, m_Zero()) &&
4717+
match(TrueVal, m_One()) &&
4718+
match(FalseVal,
4719+
m_AShr(m_Specific(CmpLHS), m_SpecificInt(BitWidth - 1)))))) {
4720+
4721+
Function *Scmp = Intrinsic::getOrInsertDeclaration(
4722+
SI.getModule(), Intrinsic::scmp, {SI.getType(), SI.getType()});
4723+
return CallInst::Create(Scmp, {CmpLHS, ConstantInt::get(SI.getType(), 0)});
4724+
}
4725+
47004726
return nullptr;
47014727
}

llvm/test/Transforms/InstCombine/scmp.ll

Lines changed: 53 additions & 3 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
@@ -747,3 +745,55 @@ define i8 @scmp_from_select_eq_and_gt_neg3(i32 %x, i32 %y) {
747745
%r = select i1 %eq, i8 0, i8 %sel1
748746
ret i8 %r
749747
}
748+
749+
define i32 @scmp_ashr(i32 %a) {
750+
; CHECK-LABEL: define i32 @scmp_ashr(
751+
; CHECK-SAME: i32 [[A:%.*]]) {
752+
; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)
753+
; CHECK-NEXT: ret i32 [[RETVAL_0]]
754+
;
755+
%a.lobit = ashr i32 %a, 31
756+
%cmp.inv = icmp slt i32 %a, 1
757+
%retval.0 = select i1 %cmp.inv, i32 %a.lobit, i32 1
758+
ret i32 %retval.0
759+
}
760+
761+
; select (icmp sgt X, 0), 1, ashr X, bitwidth-1 -> scmp(X, 0)
762+
define i8 @scmp_ashr_sgt_pattern(i8 %a) {
763+
; CHECK-LABEL: define i8 @scmp_ashr_sgt_pattern(
764+
; CHECK-SAME: i8 [[A:%.*]]) {
765+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i8(i8 [[A]], i8 0)
766+
; CHECK-NEXT: ret i8 [[R]]
767+
;
768+
%a.lobit = ashr i8 %a, 7
769+
%cmp = icmp sgt i8 %a, 0
770+
%retval = select i1 %cmp, i8 1, i8 %a.lobit
771+
ret i8 %retval
772+
}
773+
774+
; select (icmp slt X, 1), ashr X, bitwidth-1, 1 -> scmp(X, 0)
775+
define i8 @scmp_ashr_slt_pattern(i8 %a) {
776+
; CHECK-LABEL: define i8 @scmp_ashr_slt_pattern(
777+
; CHECK-SAME: i8 [[A:%.*]]) {
778+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i8(i8 [[A]], i8 0)
779+
; CHECK-NEXT: ret i8 [[R]]
780+
;
781+
%a.lobit = ashr i8 %a, 7
782+
%cmp = icmp slt i8 %a, 1
783+
%retval = select i1 %cmp, i8 %a.lobit, i8 1
784+
ret i8 %retval
785+
}
786+
787+
define i8 @scmp_ashr_slt_pattern_neg(i8 %a) {
788+
; CHECK-LABEL: define i8 @scmp_ashr_slt_pattern_neg(
789+
; CHECK-SAME: i8 [[A:%.*]]) {
790+
; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr i8 [[A]], 4
791+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A]], 1
792+
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[CMP]], i8 [[A_LOBIT]], i8 1
793+
; CHECK-NEXT: ret i8 [[RETVAL]]
794+
;
795+
%a.lobit = ashr i8 %a, 4
796+
%cmp = icmp slt i8 %a, 1
797+
%retval = select i1 %cmp, i8 %a.lobit, i8 1
798+
ret i8 %retval
799+
}

0 commit comments

Comments
 (0)