Skip to content

Commit 775d107

Browse files
authored
Merge branch 'main' into main
2 parents d7a38e2 + 8c05b5c commit 775d107

File tree

9 files changed

+388
-33
lines changed

9 files changed

+388
-33
lines changed

.ci/premerge_advisor_upload.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ def main(commit_sha, workflow_run_number, build_log_files):
2323
)
2424
test_failures = generate_test_report_lib.get_failures(junit_objects)
2525
source = "pull_request" if "GITHUB_ACTIONS" in os.environ else "postcommit"
26+
current_platform = f"{platform.system()}-{platform.machine()}".lower()
2627
failure_info = {
2728
"source_type": source,
2829
"base_commit_sha": commit_sha,
2930
"source_id": workflow_run_number,
3031
"failures": [],
32+
"platform": current_platform,
3133
}
3234
if test_failures:
3335
for name, failure_message in test_failures:

compiler-rt/cmake/Modules/CompilerRTAIXUtils.cmake

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ macro(archive_aix_libatomic name libname)
3434
if(TARGET ${target})
3535
file(MAKE_DIRECTORY ${output_dir})
3636
add_custom_command(OUTPUT "${output_dir}/libatomic.so.1"
37-
POST_BUILD
3837
COMMAND ${CMAKE_COMMAND} -E
3938
copy "$<TARGET_FILE:${target}>"
4039
"${output_dir}/libatomic.so.1"
4140
# If built with MODULE, F_LOADONLY is set.
42-
# We have to remove this flag at POST_BUILD.
4341
COMMAND ${CMAKE_STRIP} -X32_64 -E
4442
"${output_dir}/libatomic.so.1"
4543
DEPENDS ${target})

llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ inline bind_ty<const SCEVAddExpr> m_scev_Add(const SCEVAddExpr *&V) {
9595
return V;
9696
}
9797

98+
inline bind_ty<const SCEVMulExpr> m_scev_Mul(const SCEVMulExpr *&V) {
99+
return V;
100+
}
101+
98102
/// Match a specified const SCEV *.
99103
struct specificscev_ty {
100104
const SCEV *Expr;
@@ -284,14 +288,10 @@ template <typename Op0_t, typename Op1_t> struct SCEVURem_match {
284288
<< SE.getTypeSizeInBits(TruncTy));
285289
return Op0.match(LHS) && Op1.match(RHS);
286290
}
287-
const auto *Add = dyn_cast<SCEVAddExpr>(Expr);
288-
if (Add == nullptr || Add->getNumOperands() != 2)
289-
return false;
290-
291-
const SCEV *A = Add->getOperand(1);
292-
const auto *Mul = dyn_cast<SCEVMulExpr>(Add->getOperand(0));
293291

294-
if (Mul == nullptr)
292+
const SCEV *A;
293+
const SCEVMulExpr *Mul;
294+
if (!SCEVPatternMatch::match(Expr, m_scev_Add(m_scev_Mul(Mul), m_SCEV(A))))
295295
return false;
296296

297297
const auto MatchURemWithDivisor = [&](const SCEV *B) {

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4623,17 +4623,11 @@ const SCEV *ScalarEvolution::getNegativeSCEV(const SCEV *V,
46234623

46244624
/// If Expr computes ~A, return A else return nullptr
46254625
static const SCEV *MatchNotExpr(const SCEV *Expr) {
4626-
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Expr);
4627-
if (!Add || Add->getNumOperands() != 2 ||
4628-
!Add->getOperand(0)->isAllOnesValue())
4629-
return nullptr;
4630-
4631-
const SCEVMulExpr *AddRHS = dyn_cast<SCEVMulExpr>(Add->getOperand(1));
4632-
if (!AddRHS || AddRHS->getNumOperands() != 2 ||
4633-
!AddRHS->getOperand(0)->isAllOnesValue())
4634-
return nullptr;
4635-
4636-
return AddRHS->getOperand(1);
4626+
const SCEV *MulOp;
4627+
if (match(Expr, m_scev_Add(m_scev_AllOnes(),
4628+
m_scev_Mul(m_scev_AllOnes(), m_SCEV(MulOp)))))
4629+
return MulOp;
4630+
return nullptr;
46374631
}
46384632

46394633
/// Return a SCEV corresponding to ~V = -1-V
@@ -12220,12 +12214,11 @@ ScalarEvolution::computeConstantDifference(const SCEV *More, const SCEV *Less) {
1222012214
// Try to match a common constant multiply.
1222112215
auto MatchConstMul =
1222212216
[](const SCEV *S) -> std::optional<std::pair<const SCEV *, APInt>> {
12223-
auto *M = dyn_cast<SCEVMulExpr>(S);
12224-
if (!M || M->getNumOperands() != 2 ||
12225-
!isa<SCEVConstant>(M->getOperand(0)))
12226-
return std::nullopt;
12227-
return {
12228-
{M->getOperand(1), cast<SCEVConstant>(M->getOperand(0))->getAPInt()}};
12217+
const APInt *C;
12218+
const SCEV *Op;
12219+
if (match(S, m_scev_Mul(m_scev_APInt(C), m_SCEV(Op))))
12220+
return {{Op, *C}};
12221+
return std::nullopt;
1222912222
};
1223012223
if (auto MatchedMore = MatchConstMul(More)) {
1223112224
if (auto MatchedLess = MatchConstMul(Less)) {

llvm/lib/TargetParser/Unix/Host.inc

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,30 @@ static std::string updateTripleOSVersion(std::string TargetTripleString) {
5959
if (TT.getOS() == Triple::AIX && !TT.getOSMajorVersion()) {
6060
struct utsname name;
6161
if (uname(&name) != -1) {
62+
std::string release = name.release;
63+
64+
if (strcmp(name.sysname, "OS400") == 0) {
65+
/*
66+
PASE uses different versioning system than AIX.
67+
The following table shows the currently supported PASE
68+
releases and the corresponding AIX release:
69+
--------------------------
70+
PASE | AIX
71+
--------------------------
72+
V7R4 | 7.2 (TL2)
73+
--------------------------
74+
V7R5 | 7.2 (TL5)
75+
--------------------------
76+
V7R6 | 7.3 (TL1)
77+
--------------------------
78+
*/
79+
release = (release == "4" || release == "5") ? "2" : "3";
80+
}
81+
6282
std::string NewOSName = std::string(Triple::getOSTypeName(Triple::AIX));
6383
NewOSName += name.version;
6484
NewOSName += '.';
65-
NewOSName += name.release;
85+
NewOSName += release;
6686
NewOSName += ".0.0";
6787
TT.setOSName(NewOSName);
6888
return TT.str();

mlir/lib/Bindings/Python/IRCore.cpp

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2730,14 +2730,68 @@ class PyOpAttributeMap {
27302730
operation->get(), toMlirStringRef(name)));
27312731
}
27322732

2733+
static void
2734+
forEachAttr(MlirOperation op,
2735+
llvm::function_ref<void(MlirStringRef, MlirAttribute)> fn) {
2736+
intptr_t n = mlirOperationGetNumAttributes(op);
2737+
for (intptr_t i = 0; i < n; ++i) {
2738+
MlirNamedAttribute na = mlirOperationGetAttribute(op, i);
2739+
MlirStringRef name = mlirIdentifierStr(na.name);
2740+
fn(name, na.attribute);
2741+
}
2742+
}
2743+
27332744
static void bind(nb::module_ &m) {
27342745
nb::class_<PyOpAttributeMap>(m, "OpAttributeMap")
27352746
.def("__contains__", &PyOpAttributeMap::dunderContains)
27362747
.def("__len__", &PyOpAttributeMap::dunderLen)
27372748
.def("__getitem__", &PyOpAttributeMap::dunderGetItemNamed)
27382749
.def("__getitem__", &PyOpAttributeMap::dunderGetItemIndexed)
27392750
.def("__setitem__", &PyOpAttributeMap::dunderSetItem)
2740-
.def("__delitem__", &PyOpAttributeMap::dunderDelItem);
2751+
.def("__delitem__", &PyOpAttributeMap::dunderDelItem)
2752+
.def("__iter__",
2753+
[](PyOpAttributeMap &self) {
2754+
nb::list keys;
2755+
PyOpAttributeMap::forEachAttr(
2756+
self.operation->get(),
2757+
[&](MlirStringRef name, MlirAttribute) {
2758+
keys.append(nb::str(name.data, name.length));
2759+
});
2760+
return nb::iter(keys);
2761+
})
2762+
.def("keys",
2763+
[](PyOpAttributeMap &self) {
2764+
nb::list out;
2765+
PyOpAttributeMap::forEachAttr(
2766+
self.operation->get(),
2767+
[&](MlirStringRef name, MlirAttribute) {
2768+
out.append(nb::str(name.data, name.length));
2769+
});
2770+
return out;
2771+
})
2772+
.def("values",
2773+
[](PyOpAttributeMap &self) {
2774+
nb::list out;
2775+
PyOpAttributeMap::forEachAttr(
2776+
self.operation->get(),
2777+
[&](MlirStringRef, MlirAttribute attr) {
2778+
out.append(PyAttribute(self.operation->getContext(), attr)
2779+
.maybeDownCast());
2780+
});
2781+
return out;
2782+
})
2783+
.def("items", [](PyOpAttributeMap &self) {
2784+
nb::list out;
2785+
PyOpAttributeMap::forEachAttr(
2786+
self.operation->get(),
2787+
[&](MlirStringRef name, MlirAttribute attr) {
2788+
out.append(nb::make_tuple(
2789+
nb::str(name.data, name.length),
2790+
PyAttribute(self.operation->getContext(), attr)
2791+
.maybeDownCast()));
2792+
});
2793+
return out;
2794+
});
27412795
}
27422796

27432797
private:

mlir/lib/Dialect/Affine/IR/AffineOps.cpp

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,141 @@ static LogicalResult replaceAffineMinBoundingBoxExpression(AffineMinOp minOp,
11251125
return success(*map != initialMap);
11261126
}
11271127

1128+
/// Recursively traverse `e`. If `e` or one of its sub-expressions has the form
1129+
/// e1 + e2 + ... + eK, where the e_i are a super(multi)set of `exprsToRemove`,
1130+
/// place a map between e and `newVal` + sum({e1, e2, .. eK} - exprsToRemove)
1131+
/// into `replacementsMap`. If no entries were added to `replacementsMap`,
1132+
/// nothing was found.
1133+
static void shortenAddChainsContainingAll(
1134+
AffineExpr e, const llvm::SmallDenseSet<AffineExpr, 4> &exprsToRemove,
1135+
AffineExpr newVal, DenseMap<AffineExpr, AffineExpr> &replacementsMap) {
1136+
auto binOp = dyn_cast<AffineBinaryOpExpr>(e);
1137+
if (!binOp)
1138+
return;
1139+
AffineExpr lhs = binOp.getLHS();
1140+
AffineExpr rhs = binOp.getRHS();
1141+
if (binOp.getKind() != AffineExprKind::Add) {
1142+
shortenAddChainsContainingAll(lhs, exprsToRemove, newVal, replacementsMap);
1143+
shortenAddChainsContainingAll(rhs, exprsToRemove, newVal, replacementsMap);
1144+
return;
1145+
}
1146+
SmallVector<AffineExpr> toPreserve;
1147+
llvm::SmallDenseSet<AffineExpr, 4> ourTracker(exprsToRemove);
1148+
AffineExpr thisTerm = rhs;
1149+
AffineExpr nextTerm = lhs;
1150+
1151+
while (thisTerm) {
1152+
if (!ourTracker.erase(thisTerm)) {
1153+
toPreserve.push_back(thisTerm);
1154+
shortenAddChainsContainingAll(thisTerm, exprsToRemove, newVal,
1155+
replacementsMap);
1156+
}
1157+
auto nextBinOp = dyn_cast_if_present<AffineBinaryOpExpr>(nextTerm);
1158+
if (!nextBinOp || nextBinOp.getKind() != AffineExprKind::Add) {
1159+
thisTerm = nextTerm;
1160+
nextTerm = AffineExpr();
1161+
} else {
1162+
thisTerm = nextBinOp.getRHS();
1163+
nextTerm = nextBinOp.getLHS();
1164+
}
1165+
}
1166+
if (!ourTracker.empty())
1167+
return;
1168+
// We reverse the terms to be preserved here in order to preserve
1169+
// associativity between them.
1170+
AffineExpr newExpr = newVal;
1171+
for (AffineExpr preserved : llvm::reverse(toPreserve))
1172+
newExpr = newExpr + preserved;
1173+
replacementsMap.insert({e, newExpr});
1174+
}
1175+
1176+
/// If this map contains of the expression `x_1 + x_1 * C_1 + ... x_n * C_N +
1177+
/// ...` (not necessarily in order) where the set of the `x_i` is the set of
1178+
/// outputs of an `affine.delinearize_index` whos inverse is that expression,
1179+
/// replace that expression with the input of that delinearize_index op.
1180+
///
1181+
/// `unitDimInput` is the input that was detected as the potential start to this
1182+
/// replacement chain - if it isn't the rightmost result of the delinearization,
1183+
/// this method fails. (This is intended to ensure we don't have redundant scans
1184+
/// over the same expression).
1185+
///
1186+
/// While this currently only handles delinearizations with a constant basis,
1187+
/// that isn't a fundamental limitation.
1188+
///
1189+
/// This is a utility function for `replaceDimOrSym` below.
1190+
static LogicalResult replaceAffineDelinearizeIndexInverseExpression(
1191+
AffineDelinearizeIndexOp delinOp, Value resultToReplace, AffineMap *map,
1192+
SmallVectorImpl<Value> &dims, SmallVectorImpl<Value> &syms) {
1193+
if (!delinOp.getDynamicBasis().empty())
1194+
return failure();
1195+
if (resultToReplace != delinOp.getMultiIndex().back())
1196+
return failure();
1197+
1198+
MLIRContext *ctx = delinOp.getContext();
1199+
SmallVector<AffineExpr> resToExpr(delinOp.getNumResults(), AffineExpr());
1200+
for (auto [pos, dim] : llvm::enumerate(dims)) {
1201+
auto asResult = dyn_cast_if_present<OpResult>(dim);
1202+
if (!asResult)
1203+
continue;
1204+
if (asResult.getOwner() == delinOp.getOperation())
1205+
resToExpr[asResult.getResultNumber()] = getAffineDimExpr(pos, ctx);
1206+
}
1207+
for (auto [pos, sym] : llvm::enumerate(syms)) {
1208+
auto asResult = dyn_cast_if_present<OpResult>(sym);
1209+
if (!asResult)
1210+
continue;
1211+
if (asResult.getOwner() == delinOp.getOperation())
1212+
resToExpr[asResult.getResultNumber()] = getAffineSymbolExpr(pos, ctx);
1213+
}
1214+
if (llvm::is_contained(resToExpr, AffineExpr()))
1215+
return failure();
1216+
1217+
bool isDimReplacement = llvm::all_of(resToExpr, llvm::IsaPred<AffineDimExpr>);
1218+
int64_t stride = 1;
1219+
llvm::SmallDenseSet<AffineExpr, 4> expectedExprs;
1220+
// This isn't zip_equal since sometimes the delinearize basis is missing a
1221+
// size for the first result.
1222+
for (auto [binding, size] : llvm::zip(
1223+
llvm::reverse(resToExpr), llvm::reverse(delinOp.getStaticBasis()))) {
1224+
expectedExprs.insert(binding * getAffineConstantExpr(stride, ctx));
1225+
stride *= size;
1226+
}
1227+
if (resToExpr.size() != delinOp.getStaticBasis().size())
1228+
expectedExprs.insert(resToExpr[0] * stride);
1229+
1230+
DenseMap<AffineExpr, AffineExpr> replacements;
1231+
AffineExpr delinInExpr = isDimReplacement
1232+
? getAffineDimExpr(dims.size(), ctx)
1233+
: getAffineSymbolExpr(syms.size(), ctx);
1234+
1235+
for (AffineExpr e : map->getResults())
1236+
shortenAddChainsContainingAll(e, expectedExprs, delinInExpr, replacements);
1237+
if (replacements.empty())
1238+
return failure();
1239+
1240+
AffineMap origMap = *map;
1241+
if (isDimReplacement)
1242+
dims.push_back(delinOp.getLinearIndex());
1243+
else
1244+
syms.push_back(delinOp.getLinearIndex());
1245+
*map = origMap.replace(replacements, dims.size(), syms.size());
1246+
1247+
// Blank out dead dimensions and symbols
1248+
for (AffineExpr e : resToExpr) {
1249+
if (auto d = dyn_cast<AffineDimExpr>(e)) {
1250+
unsigned pos = d.getPosition();
1251+
if (!map->isFunctionOfDim(pos))
1252+
dims[pos] = nullptr;
1253+
}
1254+
if (auto s = dyn_cast<AffineSymbolExpr>(e)) {
1255+
unsigned pos = s.getPosition();
1256+
if (!map->isFunctionOfSymbol(pos))
1257+
syms[pos] = nullptr;
1258+
}
1259+
}
1260+
return success();
1261+
}
1262+
11281263
/// Replace all occurrences of AffineExpr at position `pos` in `map` by the
11291264
/// defining AffineApplyOp expression and operands.
11301265
/// When `dimOrSymbolPosition < dims.size()`, AffineDimExpr@[pos] is replaced.
@@ -1157,6 +1292,11 @@ static LogicalResult replaceDimOrSym(AffineMap *map,
11571292
syms);
11581293
}
11591294

1295+
if (auto delinOp = v.getDefiningOp<affine::AffineDelinearizeIndexOp>()) {
1296+
return replaceAffineDelinearizeIndexInverseExpression(delinOp, v, map, dims,
1297+
syms);
1298+
}
1299+
11601300
auto affineApply = v.getDefiningOp<AffineApplyOp>();
11611301
if (!affineApply)
11621302
return failure();

0 commit comments

Comments
 (0)