Skip to content

Commit beb4a48

Browse files
authored
[InstCombine] Use known bits to simplify mask in foldSelectICmpAnd (#128741)
Make use of known bits when trying to decompose a select/icmp bittest and folding it into an and. This means we can fold when additional information, for instance via a range attribute or metadata, allows us to conclude that the resulting mask is in fact a power of two.
1 parent cd54d58 commit beb4a48

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ static Instruction *foldSelectBinOpIdentity(SelectInst &Sel,
120120
/// With some variations depending if FC is larger than TC, or the shift
121121
/// isn't needed, or the bit widths don't match.
122122
static Value *foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp,
123-
InstCombiner::BuilderTy &Builder) {
123+
InstCombiner::BuilderTy &Builder,
124+
const SimplifyQuery &SQ) {
124125
const APInt *SelTC, *SelFC;
125126
if (!match(Sel.getTrueValue(), m_APInt(SelTC)) ||
126127
!match(Sel.getFalseValue(), m_APInt(SelFC)))
@@ -148,11 +149,14 @@ static Value *foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp,
148149
} else if (auto Res = decomposeBitTestICmp(Cmp->getOperand(0),
149150
Cmp->getOperand(1), Pred)) {
150151
assert(ICmpInst::isEquality(Res->Pred) && "Not equality test?");
151-
if (!Res->Mask.isPowerOf2())
152+
AndMask = Res->Mask;
153+
V = Res->X;
154+
KnownBits Known =
155+
computeKnownBits(V, /*Depth=*/0, SQ.getWithInstruction(&Sel));
156+
AndMask &= Known.getMaxValue();
157+
if (!AndMask.isPowerOf2())
152158
return nullptr;
153159

154-
V = Res->X;
155-
AndMask = Res->Mask;
156160
Pred = Res->Pred;
157161
CreateAnd = true;
158162
} else {
@@ -1957,7 +1961,7 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
19571961
tryToReuseConstantFromSelectInComparison(SI, *ICI, *this))
19581962
return NewSel;
19591963

1960-
if (Value *V = foldSelectICmpAnd(SI, ICI, Builder))
1964+
if (Value *V = foldSelectICmpAnd(SI, ICI, Builder, SQ))
19611965
return replaceInstUsesWith(SI, V);
19621966

19631967
// NOTE: if we wanted to, this is where to detect integer MIN/MAX

llvm/test/Transforms/InstCombine/select-icmp-and.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,3 +912,35 @@ define i16 @select_trunc_nuw_bittest_or(i8 %x) {
912912
%res = or i16 4, %select
913913
ret i16 %res
914914
}
915+
916+
define i16 @select_icmp_bittest_range(i16 range (i16 0, 512) %a) {
917+
; CHECK-LABEL: @select_icmp_bittest_range(
918+
; CHECK-NEXT: [[RES:%.*]] = and i16 [[A:%.*]], 256
919+
; CHECK-NEXT: ret i16 [[RES]]
920+
;
921+
%cmp = icmp ult i16 %a, 256
922+
%res = select i1 %cmp, i16 0, i16 256
923+
ret i16 %res
924+
}
925+
926+
define i16 @select_icmp_bittest_range_negative_test(i16 range (i16 0, 513) %a) {
927+
; CHECK-LABEL: @select_icmp_bittest_range_negative_test(
928+
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i16 [[A:%.*]], 256
929+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i16 0, i16 256
930+
; CHECK-NEXT: ret i16 [[RES]]
931+
;
932+
%cmp = icmp ult i16 %a, 256
933+
%res = select i1 %cmp, i16 0, i16 256
934+
ret i16 %res
935+
}
936+
937+
define i16 @select_icmp_bittest_range_negative_test2(i16 range (i16 0, 512) %a) {
938+
; CHECK-LABEL: @select_icmp_bittest_range_negative_test2(
939+
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i16 [[A:%.*]], 255
940+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i16 0, i16 255
941+
; CHECK-NEXT: ret i16 [[RES]]
942+
;
943+
%cmp = icmp ult i16 %a, 255
944+
%res = select i1 %cmp, i16 0, i16 255
945+
ret i16 %res
946+
}

0 commit comments

Comments
 (0)