Skip to content

Commit bf113b8

Browse files
committed
Adding missed optimisation
1 parent a860a3d commit bf113b8

File tree

6 files changed

+85
-18
lines changed

6 files changed

+85
-18
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, Value *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
@@ -752,9 +752,9 @@ static void computeKnownBitsFromICmpCond(const Value *V, ICmpInst *Cmp,
752752
computeKnownBitsFromCmp(V, Pred, LHS, RHS, Known, SQ);
753753
}
754754

755-
static void computeKnownBitsFromCond(const Value *V, Value *Cond,
756-
KnownBits &Known, unsigned Depth,
757-
const SimplifyQuery &SQ, bool Invert) {
755+
void llvm::computeKnownBitsFromCond(const Value *V, Value *Cond,
756+
KnownBits &Known, unsigned Depth,
757+
const SimplifyQuery &SQ, bool Invert) {
758758
Value *A, *B;
759759
if (Depth < MaxAnalysisRecursionDepth &&
760760
match(Cond, m_LogicalOp(m_Value(A), m_Value(B)))) {

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,62 @@ static Value *foldAbsDiff(ICmpInst *Cmp, Value *TVal, Value *FVal,
10781078
return nullptr;
10791079
}
10801080

1081+
/// Attempts to fold (AND %A constant) --> %A
1082+
/// if all bits that are zero in the negated constant
1083+
/// are also zero in A's known zero bits.
1084+
static Value *foldAndMaskPattern(Value *V, Value *Cmp, SelectInst &SI,
1085+
InstCombinerImpl &IC, unsigned Depth = 0) {
1086+
1087+
Value *A;
1088+
const APInt *MaskedConstant;
1089+
1090+
if (match(V, m_And(m_Value(A), m_APInt(MaskedConstant))) &&
1091+
isGuaranteedNotToBeUndef(A)) {
1092+
KnownBits Known = IC.computeKnownBits(A, 0, &SI);
1093+
IC.computeKnownBitsFromCond(A, Cmp, Known, 0, &SI, false);
1094+
if ((~(*MaskedConstant)).isSubsetOf(Known.Zero))
1095+
return A;
1096+
}
1097+
1098+
auto *I = dyn_cast<Instruction>(V);
1099+
if (!I || !isSafeToSpeculativelyExecute(I) || Depth >= 2)
1100+
return nullptr;
1101+
1102+
bool Changed = false;
1103+
for (unsigned i = 0; i < I->getNumOperands(); ++i) {
1104+
llvm::Value *Operand = I->getOperand(i);
1105+
1106+
if (std::any_of(Operand->user_begin(), Operand->user_end(),
1107+
[I](const User *User) { return User != I; }))
1108+
break;
1109+
1110+
Value *NewOp = foldAndMaskPattern(Operand, Cmp, SI, IC, Depth + 1);
1111+
if (NewOp) {
1112+
IC.replaceOperand(*I, i, NewOp);
1113+
Changed = true;
1114+
}
1115+
}
1116+
1117+
return Changed ? I : nullptr;
1118+
}
1119+
1120+
/// Attmpts to fold expressions in both branches of a select instruction
1121+
/// based on KnownBits implied by the condition
1122+
// static Instruction *foldSelectWithIcmpEqAndPattern(Value *TVal, Value *FVal,
1123+
// Value *CondVal,
1124+
// SelectInst &SI,
1125+
// InstCombinerImpl &IC) {
1126+
// if (TVal->hasOneUse())
1127+
// if (Value *newTrueOp = simplifyAndMaskPattern(TVal, CondVal, SI, IC))
1128+
// return IC.replaceOperand(SI, 1, newTrueOp);
1129+
1130+
// if (FVal->hasOneUse())
1131+
// if (Value *newFalseOp = simplifyAndMaskPattern(FVal, CondVal, SI, IC))
1132+
// return IC.replaceOperand(SI, 2, newFalseOp);
1133+
1134+
// return nullptr;
1135+
// }
1136+
10811137
/// Fold the following code sequence:
10821138
/// \code
10831139
/// int a = ctlz(x & -x);
@@ -4110,5 +4166,12 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
41104166
}
41114167
}
41124168

4169+
// Attempts to recursively identify and fold (AND A constant) --> A
4170+
// in the true branch of the select if all bits
4171+
// that are zero in the negated constant are also zero in A's known zero bits.
4172+
if (TrueVal->hasOneUse())
4173+
if (Value *newTrueOp = foldAndMaskPattern(TrueVal, CondVal, SI, *this))
4174+
return replaceOperand(SI, 1, newTrueOp);
4175+
41134176
return nullptr;
41144177
}

llvm/test/Transforms/InstCombine/select-known-bits.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ define i8 @select_icmp_eq_mul_and(i8 noundef %a, i8 %b) {
66
; CHECK-SAME: i8 noundef [[A:%.*]], i8 [[B:%.*]]) {
77
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A]], 1
88
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
9-
; CHECK-NEXT: [[DIV:%.*]] = and i8 [[A]], -2
10-
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[DIV]], [[DIV]]
9+
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[A]], [[A]]
1110
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 [[B]]
1211
; CHECK-NEXT: ret i8 [[RETVAL]]
1312
;
@@ -24,8 +23,7 @@ define i8 @select_icmp_eq_mul_and_inv(i8 noundef %a, i8 %b) {
2423
; CHECK-SAME: i8 noundef [[A:%.*]], i8 [[B:%.*]]) {
2524
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A]], 1
2625
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[TMP1]], 0
27-
; CHECK-NEXT: [[DIV:%.*]] = and i8 [[A]], -2
28-
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[DIV]], [[DIV]]
26+
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[A]], [[A]]
2927
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[CMP_NOT]], i8 [[MUL]], i8 [[B]]
3028
; CHECK-NEXT: ret i8 [[RETVAL]]
3129
;
@@ -42,8 +40,7 @@ define i8 @select_icmp_eq_and(i8 noundef %a, i8 %b) {
4240
; CHECK-SAME: i8 noundef [[A:%.*]], i8 [[B:%.*]]) {
4341
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A]], 1
4442
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
45-
; CHECK-NEXT: [[DIV:%.*]] = and i8 [[A]], -2
46-
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[CMP]], i8 [[DIV]], i8 [[B]]
43+
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[CMP]], i8 [[A]], i8 [[B]]
4744
; CHECK-NEXT: ret i8 [[RETVAL]]
4845
;
4946
%1 = and i8 %a, 1
@@ -58,8 +55,7 @@ define i8 @select_icmp_eq_and_inv(i8 noundef %a, i8 %b) {
5855
; CHECK-SAME: i8 noundef [[A:%.*]], i8 [[B:%.*]]) {
5956
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A]], 1
6057
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[TMP1]], 0
61-
; CHECK-NEXT: [[DIV:%.*]] = and i8 [[A]], -2
62-
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[CMP_NOT]], i8 [[DIV]], i8 [[B]]
58+
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[CMP_NOT]], i8 [[A]], i8 [[B]]
6359
; CHECK-NEXT: ret i8 [[RETVAL]]
6460
;
6561
%1 = and i8 %a, 1

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2989,9 +2989,8 @@ define i8 @select_replacement_loop3(i32 noundef %x) {
29892989

29902990
define i16 @select_replacement_loop4(i16 noundef %p_12) {
29912991
; CHECK-LABEL: @select_replacement_loop4(
2992-
; CHECK-NEXT: [[AND1:%.*]] = and i16 [[P_12:%.*]], 1
2993-
; CHECK-NEXT: [[CMP21:%.*]] = icmp ult i16 [[P_12]], 2
2994-
; CHECK-NEXT: [[AND3:%.*]] = select i1 [[CMP21]], i16 [[AND1]], i16 0
2992+
; CHECK-NEXT: [[CMP21:%.*]] = icmp ult i16 [[P_12:%.*]], 2
2993+
; CHECK-NEXT: [[AND3:%.*]] = select i1 [[CMP21]], i16 [[P_12]], i16 0
29952994
; CHECK-NEXT: ret i16 [[AND3]]
29962995
;
29972996
%cmp1 = icmp ult i16 %p_12, 2
@@ -4671,8 +4670,7 @@ define i8 @select_knownbits_simplify(i8 noundef %x) {
46714670
; CHECK-LABEL: @select_knownbits_simplify(
46724671
; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1
46734672
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4674-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
4675-
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
4673+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[X]], i8 0
46764674
; CHECK-NEXT: ret i8 [[RES]]
46774675
;
46784676
%x.lo = and i8 %x, 1
@@ -4686,8 +4684,7 @@ define i8 @select_knownbits_simplify_nested(i8 noundef %x) {
46864684
; CHECK-LABEL: @select_knownbits_simplify_nested(
46874685
; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1
46884686
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4689-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
4690-
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[AND]], [[AND]]
4687+
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X]], [[X]]
46914688
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 0
46924689
; CHECK-NEXT: ret i8 [[RES]]
46934690
;

0 commit comments

Comments
 (0)