Skip to content

Commit e210641

Browse files
committed
Adding the missed optimisation
1 parent 195e0fa commit e210641

File tree

5 files changed

+82
-27
lines changed

5 files changed

+82
-27
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ void computeKnownBitsFromRangeMetadata(const MDNode &Ranges, KnownBits &Known);
9494
void computeKnownBitsFromContext(const Value *V, KnownBits &Known,
9595
unsigned Depth, const SimplifyQuery &Q);
9696

97+
void computeKnownBitsFromCond(const Value *V, Value *Cond, KnownBits &Known,
98+
unsigned Depth, const SimplifyQuery &SQ,
99+
bool Invert);
100+
97101
/// Using KnownBits LHS/RHS produce the known bits for logic op (and/xor/or).
98102
KnownBits analyzeKnownBitsFromAndXorOr(const Operator *I,
99103
const KnownBits &KnownLHS,

llvm/include/llvm/Transforms/InstCombine/InstCombiner.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,13 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
438438
return llvm::computeKnownBits(V, Depth, SQ.getWithInstruction(CxtI));
439439
}
440440

441+
void computeKnownBitsFromCond(const Value *V, ICmpInst *Cmp, KnownBits &Known,
442+
unsigned Depth, const Instruction *CxtI,
443+
bool Invert) const {
444+
llvm::computeKnownBitsFromCond(V, Cmp, Known, Depth,
445+
SQ.getWithInstruction(CxtI), Invert);
446+
}
447+
441448
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero = false,
442449
unsigned Depth = 0,
443450
const Instruction *CxtI = nullptr) {

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -747,9 +747,9 @@ static void computeKnownBitsFromICmpCond(const Value *V, ICmpInst *Cmp,
747747
computeKnownBitsFromCmp(V, Pred, LHS, RHS, Known, SQ);
748748
}
749749

750-
static void computeKnownBitsFromCond(const Value *V, Value *Cond,
751-
KnownBits &Known, unsigned Depth,
752-
const SimplifyQuery &SQ, bool Invert) {
750+
void llvm::computeKnownBitsFromCond(const Value *V, Value *Cond,
751+
KnownBits &Known, unsigned Depth,
752+
const SimplifyQuery &SQ, bool Invert) {
753753
Value *A, *B;
754754
if (Depth < MaxAnalysisRecursionDepth &&
755755
match(Cond, m_LogicalOp(m_Value(A), m_Value(B)))) {

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,50 @@ static Value *foldAbsDiff(ICmpInst *Cmp, Value *TVal, Value *FVal,
10731073
return nullptr;
10741074
}
10751075

1076+
// When the lsb of cond is 0:
1077+
// cond ? A & -2 : B --> cond ? A : B
1078+
// cond ? BinOp (A & -2), (A & -2) : B --> cond ? BinOp A, A : B
1079+
static Value *foldSelectWithIcmpEqAndPattern(ICmpInst *Cmp, Value *TVal,
1080+
Value *FVal,
1081+
InstCombiner::BuilderTy &Builder,
1082+
SelectInst &SI,
1083+
InstCombinerImpl &IC) {
1084+
1085+
Value *A;
1086+
ConstantInt *MaskedConstant;
1087+
1088+
// Checks if true branche matches the pattern 'A % 2'.
1089+
if (match(TVal,
1090+
m_OneUse(m_c_And(m_Value(A), m_ConstantInt(MaskedConstant)))) &&
1091+
MaskedConstant->getValue().getSExtValue() == -2) {
1092+
KnownBits Known;
1093+
Known = IC.computeKnownBits(A, 0, &SI);
1094+
IC.computeKnownBitsFromCond(A, Cmp, Known, 0, &SI, false);
1095+
if (Known.Zero[0])
1096+
return Builder.CreateSelect(Cmp, A, FVal);
1097+
else
1098+
return nullptr;
1099+
}
1100+
1101+
// Checks if true branch matches nested 'A % 2' within a binary operation.
1102+
Value *MulVal;
1103+
if (match(TVal, m_OneUse(m_BinOp(m_Value(MulVal), m_Deferred(MulVal)))))
1104+
if (match(MulVal, m_c_And(m_Value(A), m_ConstantInt(MaskedConstant))) &&
1105+
MaskedConstant->getValue().getSExtValue() == -2) {
1106+
KnownBits Known;
1107+
Known = IC.computeKnownBits(A, 0, &SI);
1108+
IC.computeKnownBitsFromCond(A, Cmp, Known, 0, &SI, false);
1109+
if (Known.Zero[0]) {
1110+
Instruction::BinaryOps OpCode = cast<BinaryOperator>(TVal)->getOpcode();
1111+
Value *NewTValue = Builder.CreateBinOp(OpCode, A, A);
1112+
return Builder.CreateSelect(Cmp, NewTValue, FVal);
1113+
} else
1114+
return nullptr;
1115+
}
1116+
1117+
return nullptr;
1118+
}
1119+
10761120
/// Fold the following code sequence:
10771121
/// \code
10781122
/// int a = ctlz(x & -x);
@@ -1812,6 +1856,7 @@ static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI,
18121856
/// Visit a SelectInst that has an ICmpInst as its first operand.
18131857
Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
18141858
ICmpInst *ICI) {
1859+
18151860
if (Instruction *NewSel = foldSelectValueEquivalence(SI, *ICI))
18161861
return NewSel;
18171862

@@ -1951,6 +1996,10 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
19511996
if (Value *V = foldAbsDiff(ICI, TrueVal, FalseVal, Builder))
19521997
return replaceInstUsesWith(SI, V);
19531998

1999+
if (Value *V = foldSelectWithIcmpEqAndPattern(ICI, TrueVal, FalseVal, Builder,
2000+
SI, *this))
2001+
return replaceInstUsesWith(SI, V);
2002+
19542003
return Changed ? &SI : nullptr;
19552004
}
19562005

@@ -2359,20 +2408,20 @@ static Instruction *foldSelectCmpBitcasts(SelectInst &Sel,
23592408
/// operand, the result of the select will always be equal to its false value.
23602409
/// For example:
23612410
///
2362-
/// %cmpxchg = cmpxchg ptr %ptr, i64 %compare, i64 %new_value seq_cst seq_cst
2363-
/// %val = extractvalue { i64, i1 } %cmpxchg, 0
2364-
/// %success = extractvalue { i64, i1 } %cmpxchg, 1
2365-
/// %sel = select i1 %success, i64 %compare, i64 %val
2366-
/// ret i64 %sel
2411+
/// %0 = cmpxchg i64* %ptr, i64 %compare, i64 %new_value seq_cst seq_cst
2412+
/// %1 = extractvalue { i64, i1 } %0, 1
2413+
/// %2 = extractvalue { i64, i1 } %0, 0
2414+
/// %3 = select i1 %1, i64 %compare, i64 %2
2415+
/// ret i64 %3
23672416
///
2368-
/// The returned value of the cmpxchg instruction (%val) is the original value
2369-
/// located at %ptr prior to any update. If the cmpxchg operation succeeds, %val
2417+
/// The returned value of the cmpxchg instruction (%2) is the original value
2418+
/// located at %ptr prior to any update. If the cmpxchg operation succeeds, %2
23702419
/// must have been equal to %compare. Thus, the result of the select is always
2371-
/// equal to %val, and the code can be simplified to:
2420+
/// equal to %2, and the code can be simplified to:
23722421
///
2373-
/// %cmpxchg = cmpxchg ptr %ptr, i64 %compare, i64 %new_value seq_cst seq_cst
2374-
/// %val = extractvalue { i64, i1 } %cmpxchg, 0
2375-
/// ret i64 %val
2422+
/// %0 = cmpxchg i64* %ptr, i64 %compare, i64 %new_value seq_cst seq_cst
2423+
/// %1 = extractvalue { i64, i1 } %0, 0
2424+
/// ret i64 %1
23762425
///
23772426
static Value *foldSelectCmpXchg(SelectInst &SI) {
23782427
// A helper that determines if V is an extractvalue instruction whose

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,9 +1460,8 @@ define i8 @select_icmp_eq_mul_and(i8 noundef %a, i8 %b) {
14601460
; CHECK-LABEL: @select_icmp_eq_mul_and(
14611461
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], 1
14621462
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
1463-
; CHECK-NEXT: [[DIV7:%.*]] = and i8 [[A]], -2
1464-
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[DIV7]], [[DIV7]]
1465-
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 [[B:%.*]]
1463+
; CHECK-NEXT: [[TMP2:%.*]] = mul i8 [[A]], [[A]]
1464+
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[TMP2]], i8 [[B:%.*]]
14661465
; CHECK-NEXT: ret i8 [[RETVAL_0]]
14671466
;
14681467
%1 = and i8 %a, 1
@@ -1477,9 +1476,8 @@ define i8 @select_icmp_eq_shl_and(i8 noundef %a, i8 %b) {
14771476
; CHECK-LABEL: @select_icmp_eq_shl_and(
14781477
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], 1
14791478
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
1480-
; CHECK-NEXT: [[DIV7:%.*]] = and i8 [[A]], -2
1481-
; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[DIV7]], [[DIV7]]
1482-
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[B:%.*]]
1479+
; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[A]], [[A]]
1480+
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[TMP2]], i8 [[B:%.*]]
14831481
; CHECK-NEXT: ret i8 [[RETVAL_0]]
14841482
;
14851483
%1 = and i8 %a, 1
@@ -1494,8 +1492,7 @@ define i8 @select_icmp_eq_and(i8 noundef %a, i8 %b) {
14941492
; CHECK-LABEL: @select_icmp_eq_and(
14951493
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], 1
14961494
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
1497-
; CHECK-NEXT: [[DIV7:%.*]] = and i8 [[A]], -2
1498-
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[DIV7]], i8 [[B:%.*]]
1495+
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[A]], i8 [[B:%.*]]
14991496
; CHECK-NEXT: ret i8 [[RETVAL_0]]
15001497
;
15011498
%1 = and i8 %a, 1
@@ -1510,9 +1507,8 @@ define i8 @select_icmp_eq_mul_and_undef(i8 %a, i8 %b) {
15101507
; CHECK-LABEL: @select_icmp_eq_mul_and_undef(
15111508
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], 1
15121509
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
1513-
; CHECK-NEXT: [[DIV7:%.*]] = and i8 [[A]], -2
1514-
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[DIV7]], [[DIV7]]
1515-
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 [[B:%.*]]
1510+
; CHECK-NEXT: [[TMP2:%.*]] = mul i8 [[A]], [[A]]
1511+
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[TMP2]], i8 [[B:%.*]]
15161512
; CHECK-NEXT: ret i8 [[RETVAL_0]]
15171513
;
15181514
%1 = and i8 %a, 1
@@ -1528,8 +1524,7 @@ define i8 @select_icmp_eq_and_undef(i8 %a, i8 %b) {
15281524
; CHECK-LABEL: @select_icmp_eq_and_undef(
15291525
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], 1
15301526
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
1531-
; CHECK-NEXT: [[DIV7:%.*]] = and i8 [[A]], -2
1532-
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[DIV7]], i8 [[B:%.*]]
1527+
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i8 [[A]], i8 [[B:%.*]]
15331528
; CHECK-NEXT: ret i8 [[RETVAL_0]]
15341529
;
15351530
%1 = and i8 %a, 1

0 commit comments

Comments
 (0)