Skip to content

Commit 9dc4ddf

Browse files
committed
merge main into amd-staging
2 parents 051ade3 + 76d2f0f commit 9dc4ddf

File tree

22 files changed

+278
-218
lines changed

22 files changed

+278
-218
lines changed

clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,12 @@ void ContainerSizeEmptyCheck::check(const MatchFinder::MatchResult &Result) {
238238
? MemberCallObject
239239
: (Pointee ? Pointee : Result.Nodes.getNodeAs<Expr>("STLObject"));
240240
FixItHint Hint;
241-
std::string ReplacementText = std::string(
242-
Lexer::getSourceText(CharSourceRange::getTokenRange(E->getSourceRange()),
243-
*Result.SourceManager, getLangOpts()));
241+
std::string ReplacementText =
242+
E->isImplicitCXXThis()
243+
? ""
244+
: std::string(Lexer::getSourceText(
245+
CharSourceRange::getTokenRange(E->getSourceRange()),
246+
*Result.SourceManager, getLangOpts()));
244247
const auto *OpCallExpr = dyn_cast<CXXOperatorCallExpr>(E);
245248
if (isBinaryOrTernary(E) || isa<UnaryOperator>(E) ||
246249
(OpCallExpr && (OpCallExpr->getOperator() == OO_Star))) {
@@ -251,6 +254,8 @@ void ContainerSizeEmptyCheck::check(const MatchFinder::MatchResult &Result) {
251254
// This can happen if the object is a smart pointer. Don't add anything
252255
// because a '->' is already there (PR#51776), just call the method.
253256
ReplacementText += "empty()";
257+
} else if (E->isImplicitCXXThis()) {
258+
ReplacementText += "empty()";
254259
} else if (E->getType()->isPointerType())
255260
ReplacementText += "->empty()";
256261
else

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ Changes in existing checks
186186
<clang-tidy/checks/portability/template-virtual-member-function>` check to
187187
avoid false positives on pure virtual member functions.
188188

189+
- Improved :doc:`readability-container-size-empty
190+
<clang-tidy/checks/readability/container-size-empty>` check by correctly
191+
generating fix-it hints when size method is called from implicit ``this``.
192+
189193
- Improved :doc:`readability-identifier-naming
190194
<clang-tidy/checks/readability/identifier-naming>` check by ignoring
191195
declarations in system headers.

clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,3 +895,16 @@ namespace PR94454 {
895895
int operator""_ci() { return 0; }
896896
auto eq = 0_ci == 0;
897897
}
898+
899+
namespace GH152387 {
900+
901+
class foo : public std::string{
902+
void doit() {
903+
if (!size()) {
904+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used to check for emptiness instead of 'size'
905+
// CHECK-FIXES: if (empty()) {
906+
}
907+
}
908+
};
909+
910+
}

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3186,6 +3186,56 @@ def CIR_AssumeOp : CIR_Op<"assume"> {
31863186
}];
31873187
}
31883188

3189+
def CIR_AssumeAlignedOp : CIR_Op<"assume_aligned", [
3190+
Pure, AllTypesMatch<["pointer", "result"]>
3191+
]> {
3192+
let summary = "Tell the optimizer that a pointer is aligned";
3193+
let description = [{
3194+
The `cir.assume_aligned` operation takes two or three arguments. The first
3195+
argument `pointer` gives the pointer value whose alignment is to be assumed,
3196+
and the second argument `align` is an integer attribute that gives the
3197+
assumed alignment.
3198+
3199+
The `offset` argument is optional. If given, it represents misalignment
3200+
offset. When it's present, this operation tells the optimizer that the
3201+
pointer is always misaligned to the alignment by `offset` bytes, a.k.a. the
3202+
pointer yielded by `(char *)pointer - offset` is aligned to the specified
3203+
alignment. Note that the `offset` argument is an SSA value rather than an
3204+
attribute, which means that you could pass a dynamically determined value
3205+
as the mialignment offset.
3206+
3207+
The result of this operation has the same value as the `pointer` argument,
3208+
but it additionally carries any alignment information indicated by this
3209+
operation.
3210+
3211+
This operation corresponds to the `__builtin_assume_aligned` builtin
3212+
function.
3213+
3214+
Example:
3215+
3216+
```mlir
3217+
// Assume that %0 is a CIR pointer value of type !cir.ptr<!s32i>
3218+
%1 = cir.assume_aligned %0 alignment 16 : !cir.ptr<!s32i>
3219+
3220+
// With a misalignment offset of 4 bytes:
3221+
%2 = cir.const #cir.int<4> : !u64i
3222+
%3 = cir.assume_aligned %0 alignment 16 [offset %2 : !u64i] : !cir.ptr<!s32i>
3223+
```
3224+
}];
3225+
3226+
let arguments = (ins CIR_PointerType:$pointer,
3227+
I64Attr:$alignment,
3228+
Optional<CIR_IntType>:$offset);
3229+
let results = (outs CIR_PointerType:$result);
3230+
3231+
let assemblyFormat = [{
3232+
$pointer
3233+
`alignment` $alignment
3234+
(`[` `offset` $offset^ `:` type($offset) `]`)?
3235+
`:` qualified(type($pointer)) attr-dict
3236+
}];
3237+
}
3238+
31893239
def CIR_AssumeSepStorageOp : CIR_Op<"assume_separate_storage", [
31903240
SameTypeOperands
31913241
]> {

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,8 +1544,7 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
15441544
// Composite arrays
15451545
if (IsArray) {
15461546
const Descriptor *Desc =
1547-
S.P.createDescriptor(NewCall, ElemType.getTypePtr(),
1548-
IsArray ? std::nullopt : Descriptor::InlineDescMD);
1547+
S.P.createDescriptor(NewCall, ElemType.getTypePtr(), std::nullopt);
15491548
Block *B =
15501549
Allocator.allocate(Desc, NumElems.getZExtValue(), S.Ctx.getEvalID(),
15511550
DynamicAllocator::Form::Operator);
@@ -1558,9 +1557,8 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
15581557
QualType AllocType = S.getASTContext().getConstantArrayType(
15591558
ElemType, NumElems, nullptr, ArraySizeModifier::Normal, 0);
15601559

1561-
const Descriptor *Desc =
1562-
S.P.createDescriptor(NewCall, AllocType.getTypePtr(),
1563-
IsArray ? std::nullopt : Descriptor::InlineDescMD);
1560+
const Descriptor *Desc = S.P.createDescriptor(NewCall, AllocType.getTypePtr(),
1561+
Descriptor::InlineDescMD);
15641562
Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
15651563
DynamicAllocator::Form::Operator);
15661564
assert(B);

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,24 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
129129
return RValue::get(nullptr);
130130
}
131131

132+
case Builtin::BI__builtin_assume_aligned: {
133+
const Expr *ptrExpr = e->getArg(0);
134+
mlir::Value ptrValue = emitScalarExpr(ptrExpr);
135+
mlir::Value offsetValue =
136+
(e->getNumArgs() > 2) ? emitScalarExpr(e->getArg(2)) : nullptr;
137+
138+
std::optional<llvm::APSInt> alignment =
139+
e->getArg(1)->getIntegerConstantExpr(getContext());
140+
assert(alignment.has_value() &&
141+
"the second argument to __builtin_assume_aligned must be an "
142+
"integral constant expression");
143+
144+
mlir::Value result =
145+
emitAlignmentAssumption(ptrValue, ptrExpr, ptrExpr->getExprLoc(),
146+
alignment->getSExtValue(), offsetValue);
147+
return RValue::get(result);
148+
}
149+
132150
case Builtin::BI__builtin_complex: {
133151
mlir::Value real = emitScalarExpr(e->getArg(0));
134152
mlir::Value imag = emitScalarExpr(e->getArg(1));

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,23 @@ CIRGenFunction::emitArrayLength(const clang::ArrayType *origArrayType,
933933
return builder.getConstInt(*currSrcLoc, SizeTy, countFromCLAs);
934934
}
935935

936+
mlir::Value CIRGenFunction::emitAlignmentAssumption(
937+
mlir::Value ptrValue, QualType ty, SourceLocation loc,
938+
SourceLocation assumptionLoc, int64_t alignment, mlir::Value offsetValue) {
939+
assert(!cir::MissingFeatures::sanitizers());
940+
return cir::AssumeAlignedOp::create(builder, getLoc(assumptionLoc), ptrValue,
941+
alignment, offsetValue);
942+
}
943+
944+
mlir::Value CIRGenFunction::emitAlignmentAssumption(
945+
mlir::Value ptrValue, const Expr *expr, SourceLocation assumptionLoc,
946+
int64_t alignment, mlir::Value offsetValue) {
947+
QualType ty = expr->getType();
948+
SourceLocation loc = expr->getExprLoc();
949+
return emitAlignmentAssumption(ptrValue, ty, loc, assumptionLoc, alignment,
950+
offsetValue);
951+
}
952+
936953
// TODO(cir): Most of this function can be shared between CIRGen
937954
// and traditional LLVM codegen
938955
void CIRGenFunction::emitVariablyModifiedType(QualType type) {

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,18 @@ class CIRGenFunction : public CIRGenTypeCache {
829829
/// ----------------------
830830
/// CIR emit functions
831831
/// ----------------------
832+
public:
833+
mlir::Value emitAlignmentAssumption(mlir::Value ptrValue, QualType ty,
834+
SourceLocation loc,
835+
SourceLocation assumptionLoc,
836+
int64_t alignment,
837+
mlir::Value offsetValue = nullptr);
838+
839+
mlir::Value emitAlignmentAssumption(mlir::Value ptrValue, const Expr *expr,
840+
SourceLocation assumptionLoc,
841+
int64_t alignment,
842+
mlir::Value offsetValue = nullptr);
843+
832844
private:
833845
void emitAndUpdateRetAlloca(clang::QualType type, mlir::Location loc,
834846
clang::CharUnits alignment);

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,29 @@ mlir::LogicalResult CIRToLLVMAssumeOpLowering::matchAndRewrite(
460460
return mlir::success();
461461
}
462462

463+
mlir::LogicalResult CIRToLLVMAssumeAlignedOpLowering::matchAndRewrite(
464+
cir::AssumeAlignedOp op, OpAdaptor adaptor,
465+
mlir::ConversionPatternRewriter &rewriter) const {
466+
SmallVector<mlir::Value, 3> opBundleArgs{adaptor.getPointer()};
467+
468+
auto alignment = mlir::LLVM::ConstantOp::create(rewriter, op.getLoc(),
469+
adaptor.getAlignmentAttr());
470+
opBundleArgs.push_back(alignment);
471+
472+
if (mlir::Value offset = adaptor.getOffset())
473+
opBundleArgs.push_back(offset);
474+
475+
auto cond = mlir::LLVM::ConstantOp::create(rewriter, op.getLoc(),
476+
rewriter.getI1Type(), 1);
477+
mlir::LLVM::AssumeOp::create(rewriter, op.getLoc(), cond, "align",
478+
opBundleArgs);
479+
480+
// The llvm.assume operation does not have a result, so we need to replace
481+
// all uses of this cir.assume_aligned operation with the input ptr itself.
482+
rewriter.replaceOp(op, adaptor.getPointer());
483+
return mlir::success();
484+
}
485+
463486
mlir::LogicalResult CIRToLLVMAssumeSepStorageOpLowering::matchAndRewrite(
464487
cir::AssumeSepStorageOp op, OpAdaptor adaptor,
465488
mlir::ConversionPatternRewriter &rewriter) const {
@@ -2173,6 +2196,7 @@ void ConvertCIRToLLVMPass::runOnOperation() {
21732196
patterns.add<
21742197
// clang-format off
21752198
CIRToLLVMAssumeOpLowering,
2199+
CIRToLLVMAssumeAlignedOpLowering,
21762200
CIRToLLVMAssumeSepStorageOpLowering,
21772201
CIRToLLVMBaseClassAddrOpLowering,
21782202
CIRToLLVMBinOpLowering,

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ class CIRToLLVMAssumeOpLowering
4444
mlir::ConversionPatternRewriter &) const override;
4545
};
4646

47+
class CIRToLLVMAssumeAlignedOpLowering
48+
: public mlir::OpConversionPattern<cir::AssumeAlignedOp> {
49+
public:
50+
using mlir::OpConversionPattern<cir::AssumeAlignedOp>::OpConversionPattern;
51+
52+
mlir::LogicalResult
53+
matchAndRewrite(cir::AssumeAlignedOp op, OpAdaptor,
54+
mlir::ConversionPatternRewriter &) const override;
55+
};
56+
4757
class CIRToLLVMAssumeSepStorageOpLowering
4858
: public mlir::OpConversionPattern<cir::AssumeSepStorageOp> {
4959
public:

0 commit comments

Comments
 (0)