Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ac0bc20
[OpenACC][CIR] Reduction combiner lowering for min/max (#163656)
erichkeane Oct 20, 2025
5c86520
[RISCV] Remove shiftop/shiftopw PatFrags. NFC (#164050)
topperc Oct 20, 2025
ad582e3
[BPF] Support for `DW_TAG_variant_part` in BTF generation (#155783)
vadorovsky Oct 20, 2025
c01a223
[lldb] Add try_lock to SBMutex (#164109)
JDevlieghere Oct 20, 2025
c0073a9
[GitHub][CI] Run clang-tidy in dedicated container (#164290)
vbvictor Oct 20, 2025
a39704f
[NFC] Add myself to CODEOWNERS for AMD dialects (#164289)
krzysz00 Oct 20, 2025
894eaf4
[ADT] Deprecate StringSwitch Cases with 4+ args. NFC. (#164276)
kuhar Oct 20, 2025
7e1f79c
[Bazel] Add more llvm tools (#163228)
HighW4y2H3ll Oct 20, 2025
6284041
[ADT] Add llvm::countr_zero_constexpr (#164188)
kazutakahirata Oct 20, 2025
ef87da0
[mlir][spirv] Remove invalid canon pattern for GL.Length (#164301)
kuhar Oct 20, 2025
c683f21
[NFC][Clang][AMDGPU] Fix upstream and downstream difference (#164304)
shiltian Oct 20, 2025
c375c41
[mlir][python] Add Pythonic wrappers for gpu ops (#163883)
ashermancinelli Oct 20, 2025
c318f82
[clang-format] Respect ColumnLimit while aligning multiline expressio…
HazardyKnusperkeks Oct 20, 2025
d4af5e6
[Unittest][Cygwin] Set $PATH when running unittests (#163947)
kikairoya Oct 20, 2025
f37b445
[NFC][OpenMP] Add small class-member use_device_ptr/addr unit tests. …
abhinavgaba Oct 20, 2025
13498bc
[clang-tools-extra][Unittest] Fix wrong reference to CMake configurat…
kikairoya Oct 20, 2025
be9c083
[CAS] Add OnDiskGraphDB and OnDiskKeyValueDB (#114102)
cachemeifyoucan Oct 20, 2025
5cd9f0f
[flang] Move parse tree tool to Parser/tools.h (#163998)
klausler Oct 20, 2025
c3d905e
[bazel] Add riscv64 linux platform (#163781)
kxxt Oct 20, 2025
9e9d67d
[debugserver][NFC] Fix unused variable warning
felipepiovezan Oct 20, 2025
670fb3e
[NFC][LLVM][CodeGen] Create header file for MIRFSDiscriminator option…
jurahul Oct 20, 2025
cd67ca2
[lldb-dap] Send an Invalidated event on thread stack change. (#163976)
da-viper Oct 20, 2025
e8b255d
Hexagon QFP Optimizer (#163843)
fhossein-quic Oct 20, 2025
fcb1a82
[libc++] Fix off-by-one error in compare-benchmarks script
ldionne Oct 20, 2025
46ab6c6
[FlowSensitive] [Optional] Fix absl::in_place (#163897)
fmayer Oct 20, 2025
dfe48e7
[flang][cuda] Update c_loc with device variable to get host address (…
clementval Oct 20, 2025
803883c
[flang][cuda][rt] Canonicalize block size values (#164321)
clementval Oct 20, 2025
35b9f20
[LV] Check for TruncInsts in canTruncateToMinimalBitwidth.
fhahn Oct 20, 2025
ca4df68
[msan][test] Add tests for target("aarch64.svcount") (#164315)
thurstond Oct 20, 2025
dc71831
[lldb-dap] use workspaceFolder in vscode configurations. (#164320)
da-viper Oct 20, 2025
437cad9
[CIR] Upstream aggregate binary assign handling (#163877)
andykaylor Oct 20, 2025
ac65da0
[mlir][spirv][test] Fork test to allow testing with assertions enable…
googlewalt Oct 20, 2025
32b534b
[lldb][doc NFC] fix typeo in reason:watchpoint desc
jasonmolenda Oct 20, 2025
e7f370f
[SLP] Check all copyable children for non-schedulable parent nodes
alexey-bataev Oct 20, 2025
c8c86ef
[ORC] Replace ORC's baked-in dependence tracking with WaitingOnGraph.…
lhames Oct 20, 2025
13ca872
Revert "[ORC] Replace ORC's baked-in dependence tracking ... (#163027)"
lhames Oct 20, 2025
cc88a3b
[bazel] Add dep for MLIR 5a112de (#164331)
rnk Oct 20, 2025
c9124a1
Fix a potential use-after-free in StopInfoBreakpoint. (#163471)
jimingham Oct 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@
/mlir/include/mlir/Interfaces/DestinationStyleOpInterface.* @matthias-springer
/mlir/lib/Interfaces/DestinationStyleOpInterface.* @matthias-springer

# AMDGPU and ROCDL dialects in MLIR.
/mlir/include/mlir/Dialect/AMDGPU @krzysz00 @kuhar
/mlir/lib/Dialect/AMDGPU @krzysz00 @kuhar
/mlir/lib/Conversion/*AMDGPU* @krzysz00 @kuhar
/mlir/lib/Conversion/*ToROCDL @krzysz00 @kuhar
/mlir/include/mlir/Dialect/LLVMIR/ROCDL* @krzysz00 @kuhar

# Bufferization Dialect in MLIR.
/mlir/include/mlir/Dialect/Bufferization @matthias-springer
/mlir/lib/Dialect/Bufferization @matthias-springer
Expand Down
23 changes: 6 additions & 17 deletions .github/workflows/pr-code-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
run:
shell: bash
container:
image: 'ghcr.io/llvm/ci-ubuntu-24.04:latest'
image: 'ghcr.io/llvm/ci-ubuntu-24.04-lint'
timeout-minutes: 60
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand All @@ -31,6 +31,11 @@ jobs:
with:
fetch-depth: 2

# FIXME: same as in ".github/workflows/pr-code-format.yml"
- name: Set Safe Directory
run: |
chown -R root $(pwd)

- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
Expand All @@ -46,22 +51,6 @@ jobs:
run: |
echo "Changed files:"
echo "$CHANGED_FILES"

# The clang tidy version should always be upgraded to the first version
# of a release cycle (x.1.0) or the last version of a release cycle, or
# if there have been relevant clang-format backports.
- name: Install clang-tidy
uses: aminya/setup-cpp@a276e6e3d1db9160db5edc458e99a30d3b109949 # v1.7.1
with:
clang-tidy: 21.1.0

- name: Setup Python env
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.13'

- name: Install Python dependencies
run: python3 -m pip install -r llvm/utils/git/requirements_linting.txt

# TODO: create special mapping for 'codegen' targets, for now build predefined set
# TODO: add entrypoint in 'compute_projects.py' that only adds a project and its direct dependencies
Expand Down
4 changes: 2 additions & 2 deletions clang-tools-extra/clangd/unittests/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@

if platform.system() == "Darwin":
shlibpath_var = "DYLD_LIBRARY_PATH"
elif platform.system() == "Windows":
elif platform.system() == "Windows" or sys.platform == "cygwin":
shlibpath_var = "PATH"
else:
shlibpath_var = "LD_LIBRARY_PATH"
config.environment[shlibpath_var] = os.path.pathsep.join(
("@SHLIBDIR@", "@LLVM_LIBS_DIR@", config.environment.get(shlibpath_var, ""))
(config.shlibdir, config.llvm_libs_dir, config.environment.get(shlibpath_var, ""))
)

# It is not realistically possible to account for all options that could
Expand Down
4 changes: 2 additions & 2 deletions clang-tools-extra/include-cleaner/test/Unit/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

if platform.system() == "Darwin":
shlibpath_var = "DYLD_LIBRARY_PATH"
elif platform.system() == "Windows":
elif platform.system() == "Windows" or sys.platform == "cygwin":
shlibpath_var = "PATH"
else:
shlibpath_var = "LD_LIBRARY_PATH"
config.environment[shlibpath_var] = os.path.pathsep.join(
("@SHLIBDIR@", "@LLVM_LIBS_DIR@", config.environment.get(shlibpath_var, ""))
(config.shlibdir, config.llvm_libs_dir, config.environment.get(shlibpath_var, ""))
)

# It is not realistically possible to account for all options that could
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/test/Unit/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

if platform.system() == "Darwin":
shlibpath_var = "DYLD_LIBRARY_PATH"
elif platform.system() == "Windows":
elif platform.system() == "Windows" or sys.platform == "cygwin":
shlibpath_var = "PATH"
else:
shlibpath_var = "LD_LIBRARY_PATH"
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -13676,6 +13676,9 @@ def err_acc_reduction_recipe_no_op
"not have a valid operation available">;
def note_acc_reduction_recipe_noop_field
: Note<"while forming combiner for compound type %0">;
def note_acc_reduction_combiner_forming
: Note<"while forming %select{|binary operator '%1'|conditional "
"operator|final assignment operator}0">;

// AMDGCN builtins diagnostics
def err_amdgcn_load_lds_size_invalid_value : Error<"invalid size value">;
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,9 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
}

/// Create a copy with inferred length.
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src) {
return cir::CopyOp::create(*this, dst.getLoc(), dst, src);
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
bool isVolatile = false) {
return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile);
}

cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
Expand Down
7 changes: 5 additions & 2 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2724,6 +2724,8 @@ def CIR_CopyOp : CIR_Op<"copy",[
type of `src` and `dst` must match and both must implement the
`DataLayoutTypeInterface`.

The `volatile` keyword indicates that the operation is volatile.

Examples:

```mlir
Expand All @@ -2734,10 +2736,11 @@ def CIR_CopyOp : CIR_Op<"copy",[

let arguments = (ins
Arg<CIR_PointerType, "", [MemWrite]>:$dst,
Arg<CIR_PointerType, "", [MemRead]>:$src
Arg<CIR_PointerType, "", [MemRead]>:$src,
UnitAttr:$is_volatile
);

let assemblyFormat = [{$src `to` $dst
let assemblyFormat = [{$src `to` $dst (`volatile` $is_volatile^)?
attr-dict `:` qualified(type($dst))
}];
let hasVerifier = 1;
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,10 @@ struct MissingFeatures {
static bool atomicInfo() { return false; }
static bool atomicInfoGetAtomicPointer() { return false; }
static bool atomicInfoGetAtomicAddress() { return false; }
static bool atomicUseLibCall() { return false; }
static bool atomicScope() { return false; }
static bool atomicSyncScopeID() { return false; }
static bool atomicTypes() { return false; }
static bool atomicUseLibCall() { return false; }

// Global ctor handling
static bool globalCtorLexOrder() { return false; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ auto nulloptTypeDecl() {
auto hasNulloptType() { return hasType(nulloptTypeDecl()); }

auto inPlaceClass() {
return recordDecl(hasAnyName("std::in_place_t", "absl::in_place_t",
"base::in_place_t", "folly::in_place_t",
"bsl::in_place_t"));
return namedDecl(hasAnyName("std::in_place_t", "absl::in_place_t",
"base::in_place_t", "folly::in_place_t",
"bsl::in_place_t"));
}

auto isOptionalNulloptConstructor() {
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,16 @@ struct CallStackRestore final : EHScopeStack::Cleanup {
};
} // namespace

/// Push the standard destructor for the given type as
/// at least a normal cleanup.
void CIRGenFunction::pushDestroy(QualType::DestructionKind dtorKind,
Address addr, QualType type) {
assert(dtorKind && "cannot push destructor for trivial type");

CleanupKind cleanupKind = getCleanupKind(dtorKind);
pushDestroy(cleanupKind, addr, type, getDestroyer(dtorKind));
}

void CIRGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr,
QualType type, Destroyer *destroyer) {
pushFullExprCleanup<DestroyObject>(cleanupKind, addr, type, destroyer);
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1626,14 +1626,15 @@ LValue CIRGenFunction::emitBinaryOperatorLValue(const BinaryOperator *e) {

/// Emit code to compute the specified expression which
/// can have any type. The result is returned as an RValue struct.
RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot) {
RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot,
bool ignoreResult) {
switch (CIRGenFunction::getEvaluationKind(e->getType())) {
case cir::TEK_Scalar:
return RValue::get(emitScalarExpr(e));
case cir::TEK_Complex:
return RValue::getComplex(emitComplexExpr(e));
case cir::TEK_Aggregate: {
if (aggSlot.isIgnored())
if (!ignoreResult && aggSlot.isIgnored())
aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),
getCounterAggTmpAsString());
emitAggExpr(e, aggSlot);
Expand Down Expand Up @@ -1869,8 +1870,7 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
/// Emit code to compute the specified expression, ignoring the result.
void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
if (e->isPRValue()) {
assert(!cir::MissingFeatures::aggValueSlot());
emitAnyExpr(e);
emitAnyExpr(e, AggValueSlot::ignored(), /*ignoreResult=*/true);
return;
}

Expand Down
123 changes: 114 additions & 9 deletions clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,73 @@ using namespace clang;
using namespace clang::CIRGen;

namespace {
// FIXME(cir): This should be a common helper between CIRGen
// and traditional CodeGen
/// Is the value of the given expression possibly a reference to or
/// into a __block variable?
static bool isBlockVarRef(const Expr *e) {
// Make sure we look through parens.
e = e->IgnoreParens();

// Check for a direct reference to a __block variable.
if (const DeclRefExpr *dre = dyn_cast<DeclRefExpr>(e)) {
const VarDecl *var = dyn_cast<VarDecl>(dre->getDecl());
return (var && var->hasAttr<BlocksAttr>());
}

// More complicated stuff.

// Binary operators.
if (const BinaryOperator *op = dyn_cast<BinaryOperator>(e)) {
// For an assignment or pointer-to-member operation, just care
// about the LHS.
if (op->isAssignmentOp() || op->isPtrMemOp())
return isBlockVarRef(op->getLHS());

// For a comma, just care about the RHS.
if (op->getOpcode() == BO_Comma)
return isBlockVarRef(op->getRHS());

// FIXME: pointer arithmetic?
return false;

// Check both sides of a conditional operator.
} else if (const AbstractConditionalOperator *op =
dyn_cast<AbstractConditionalOperator>(e)) {
return isBlockVarRef(op->getTrueExpr()) ||
isBlockVarRef(op->getFalseExpr());

// OVEs are required to support BinaryConditionalOperators.
} else if (const OpaqueValueExpr *op = dyn_cast<OpaqueValueExpr>(e)) {
if (const Expr *src = op->getSourceExpr())
return isBlockVarRef(src);

// Casts are necessary to get things like (*(int*)&var) = foo().
// We don't really care about the kind of cast here, except
// we don't want to look through l2r casts, because it's okay
// to get the *value* in a __block variable.
} else if (const CastExpr *cast = dyn_cast<CastExpr>(e)) {
if (cast->getCastKind() == CK_LValueToRValue)
return false;
return isBlockVarRef(cast->getSubExpr());

// Handle unary operators. Again, just aggressively look through
// it, ignoring the operation.
} else if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
return isBlockVarRef(uop->getSubExpr());

// Look into the base of a field access.
} else if (const MemberExpr *mem = dyn_cast<MemberExpr>(e)) {
return isBlockVarRef(mem->getBase());

// Look into the base of a subscript.
} else if (const ArraySubscriptExpr *sub = dyn_cast<ArraySubscriptExpr>(e)) {
return isBlockVarRef(sub->getBase());
}

return false;
}

class AggExprEmitter : public StmtVisitor<AggExprEmitter> {

CIRGenFunction &cgf;
Expand All @@ -41,9 +108,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
AggValueSlot ensureSlot(mlir::Location loc, QualType t) {
if (!dest.isIgnored())
return dest;

cgf.cgm.errorNYI(loc, "Slot for ignored address");
return dest;
return cgf.createAggTemp(t, loc, "agg.tmp.ensured");
}

void ensureDest(mlir::Location loc, QualType ty) {
Expand Down Expand Up @@ -89,6 +154,47 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
(void)cgf.emitCompoundStmt(*e->getSubStmt(), &retAlloca, dest);
}

void VisitBinAssign(const BinaryOperator *e) {
// For an assignment to work, the value on the right has
// to be compatible with the value on the left.
assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(),
e->getRHS()->getType()) &&
"Invalid assignment");

if (isBlockVarRef(e->getLHS()) &&
e->getRHS()->HasSideEffects(cgf.getContext())) {
cgf.cgm.errorNYI(e->getSourceRange(),
"block var reference with side effects");
return;
}

LValue lhs = cgf.emitLValue(e->getLHS());

// If we have an atomic type, evaluate into the destination and then
// do an atomic copy.
assert(!cir::MissingFeatures::atomicTypes());

// Codegen the RHS so that it stores directly into the LHS.
assert(!cir::MissingFeatures::aggValueSlotGC());
AggValueSlot lhsSlot = AggValueSlot::forLValue(
lhs, AggValueSlot::IsDestructed, AggValueSlot::IsAliased,
AggValueSlot::MayOverlap);

// A non-volatile aggregate destination might have volatile member.
if (!lhsSlot.isVolatile() && cgf.hasVolatileMember(e->getLHS()->getType()))
lhsSlot.setVolatile(true);

cgf.emitAggExpr(e->getRHS(), lhsSlot);

// Copy into the destination if the assignment isn't ignored.
emitFinalDestCopy(e->getType(), lhs);

if (!dest.isIgnored() && !dest.isExternallyDestructed() &&
e->getType().isDestructedType() == QualType::DK_nontrivial_c_struct)
cgf.pushDestroy(QualType::DK_nontrivial_c_struct, dest.getAddress(),
e->getType());
}

void VisitDeclRefExpr(DeclRefExpr *e) { emitAggLoadOfLValue(e); }

void VisitInitListExpr(InitListExpr *e);
Expand Down Expand Up @@ -186,9 +292,6 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
cgf.cgm.errorNYI(e->getSourceRange(),
"AggExprEmitter: VisitPointerToDataMemberBinaryOperator");
}
void VisitBinAssign(const BinaryOperator *e) {
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitBinAssign");
}
void VisitBinComma(const BinaryOperator *e) {
cgf.emitIgnoredExpr(e->getLHS());
Visit(e->getRHS());
Expand Down Expand Up @@ -503,7 +606,8 @@ void AggExprEmitter::emitCopy(QualType type, const AggValueSlot &dest,
LValue destLV = cgf.makeAddrLValue(dest.getAddress(), type);
LValue srcLV = cgf.makeAddrLValue(src.getAddress(), type);
assert(!cir::MissingFeatures::aggValueSlotVolatile());
cgf.emitAggregateCopy(destLV, srcLV, type, dest.mayOverlap());
cgf.emitAggregateCopy(destLV, srcLV, type, dest.mayOverlap(),
dest.isVolatile() || src.isVolatile());
}

void AggExprEmitter::emitInitializationToLValue(Expr *e, LValue lv) {
Expand Down Expand Up @@ -804,7 +908,8 @@ void CIRGenFunction::emitAggExpr(const Expr *e, AggValueSlot slot) {
}

void CIRGenFunction::emitAggregateCopy(LValue dest, LValue src, QualType ty,
AggValueSlot::Overlap_t mayOverlap) {
AggValueSlot::Overlap_t mayOverlap,
bool isVolatile) {
// TODO(cir): this function needs improvements, commented code for now since
// this will be touched again soon.
assert(!ty->isAnyComplexType() && "Unexpected copy of complex");
Expand Down Expand Up @@ -860,7 +965,7 @@ void CIRGenFunction::emitAggregateCopy(LValue dest, LValue src, QualType ty,
cgm.errorNYI("emitAggregateCopy: GC");

[[maybe_unused]] cir::CopyOp copyOp =
builder.createCopy(destPtr.getPointer(), srcPtr.getPointer());
builder.createCopy(destPtr.getPointer(), srcPtr.getPointer(), isVolatile);

assert(!cir::MissingFeatures::opTBAA());
}
Expand Down
Loading
Loading