Skip to content

Commit 981ed72

Browse files
committed
[NFC][SCEV] Refactor createNodeForSelectViaUMinSeq() out of createNodeForSelectOrPHIViaUMinSeq()
1 parent fd20eb5 commit 981ed72

File tree

1 file changed

+50
-22
lines changed

1 file changed

+50
-22
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5997,36 +5997,64 @@ const SCEV *ScalarEvolution::createNodeForSelectOrPHIInstWithICmpInstCond(
59975997
return getUnknown(I);
59985998
}
59995999

6000-
const SCEV *ScalarEvolution::createNodeForSelectOrPHIViaUMinSeq(
6001-
Value *V, Value *Cond, Value *TrueVal, Value *FalseVal) {
6002-
// For now, only deal with i1-typed `select`s.
6003-
if (!V->getType()->isIntegerTy(1) || !Cond->getType()->isIntegerTy(1) ||
6004-
!TrueVal->getType()->isIntegerTy(1) ||
6005-
!FalseVal->getType()->isIntegerTy(1))
6006-
return getUnknown(V);
6000+
static Optional<const SCEV *>
6001+
createNodeForSelectViaUMinSeq(ScalarEvolution *SE, const SCEV *CondExpr,
6002+
const SCEV *TrueExpr, const SCEV *FalseExpr) {
6003+
assert(CondExpr->getType()->isIntegerTy(1) &&
6004+
TrueExpr->getType() == FalseExpr->getType() &&
6005+
TrueExpr->getType()->isIntegerTy(1) &&
6006+
"Unexpected operands of a select.");
60076007

60086008
// i1 cond ? i1 x : i1 C --> C + (i1 cond ? (i1 x - i1 C) : i1 0)
60096009
// --> C + (umin_seq cond, x - C)
60106010
//
60116011
// i1 cond ? i1 C : i1 x --> C + (i1 cond ? i1 0 : (i1 x - i1 C))
60126012
// --> C + (i1 ~cond ? (i1 x - i1 C) : i1 0)
60136013
// --> C + (umin_seq ~cond, x - C)
6014-
if (isa<ConstantInt>(TrueVal) || isa<ConstantInt>(FalseVal)) {
6015-
const SCEV *CondExpr = getSCEV(Cond);
6016-
const SCEV *TrueExpr = getSCEV(TrueVal);
6017-
const SCEV *FalseExpr = getSCEV(FalseVal);
6018-
const SCEV *X, *C;
6019-
if (isa<ConstantInt>(TrueVal)) {
6020-
CondExpr = getNotSCEV(CondExpr);
6021-
X = FalseExpr;
6022-
C = TrueExpr;
6023-
} else {
6024-
X = TrueExpr;
6025-
C = FalseExpr;
6026-
}
6027-
return getAddExpr(
6028-
C, getUMinExpr(CondExpr, getMinusSCEV(X, C), /*Sequential=*/true));
6014+
6015+
// FIXME: while we can't legally model the case where both of the hands
6016+
// are fully variable, we only require that the *difference* is constant.
6017+
if (!isa<SCEVConstant>(TrueExpr) && !isa<SCEVConstant>(FalseExpr))
6018+
return None;
6019+
6020+
const SCEV *X, *C;
6021+
if (isa<SCEVConstant>(TrueExpr)) {
6022+
CondExpr = SE->getNotSCEV(CondExpr);
6023+
X = FalseExpr;
6024+
C = TrueExpr;
6025+
} else {
6026+
X = TrueExpr;
6027+
C = FalseExpr;
60296028
}
6029+
return SE->getAddExpr(C, SE->getUMinExpr(CondExpr, SE->getMinusSCEV(X, C),
6030+
/*Sequential=*/true));
6031+
}
6032+
6033+
static Optional<const SCEV *> createNodeForSelectViaUMinSeq(ScalarEvolution *SE,
6034+
Value *Cond,
6035+
Value *TrueVal,
6036+
Value *FalseVal) {
6037+
if (!isa<ConstantInt>(TrueVal) && !isa<ConstantInt>(FalseVal))
6038+
return None;
6039+
6040+
return createNodeForSelectViaUMinSeq(
6041+
SE, SE->getSCEV(Cond), SE->getSCEV(TrueVal), SE->getSCEV(FalseVal));
6042+
}
6043+
6044+
const SCEV *ScalarEvolution::createNodeForSelectOrPHIViaUMinSeq(
6045+
Value *V, Value *Cond, Value *TrueVal, Value *FalseVal) {
6046+
assert(Cond->getType()->isIntegerTy(1) && "Select condition is not an i1?");
6047+
assert(TrueVal->getType() == FalseVal->getType() &&
6048+
V->getType() == TrueVal->getType() &&
6049+
"Types of select hands and of the result must match.");
6050+
6051+
// For now, only deal with i1-typed `select`s.
6052+
if (!V->getType()->isIntegerTy(1))
6053+
return getUnknown(V);
6054+
6055+
if (Optional<const SCEV *> S =
6056+
createNodeForSelectViaUMinSeq(this, Cond, TrueVal, FalseVal))
6057+
return *S;
60306058

60316059
return getUnknown(V);
60326060
}

0 commit comments

Comments
 (0)