Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AutoBump] Merge with 21ba91c4 (Jun 17) (81) #345

Merged
merged 39 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
fb59d9b
[DebugInfo] Update sroa-extract-bits.ll test (#95774)
john-brawn-arm Jun 17, 2024
457e895
[CodeGen] Do not include $noreg in any regmask operands. NFCI. (#95775)
jayfoad Jun 17, 2024
0432221
[flang][debug] Support allocatables. (#95557)
abidh Jun 17, 2024
96e8d0f
[AArch64] Refactor creation of a shuffle mask for TBL (NFC) (#92529)
momchil-velikov Jun 17, 2024
405882d
AMDGPU: Fix legalization for llvm.amdgcn.struct.buffer.atomic.fadd.v2…
arsenm Jun 16, 2024
0cfdce8
[libc++] Guard transitive include of `<locale>` with availability mac…
var-const Jun 17, 2024
b75e7c6
[flang] Add -mlink-builtin-bitcode option to fc1 (#94763)
jsjodin Jun 17, 2024
7767f0d
[InstCombine] Add test for #95547 (NFC)
nikic Jun 17, 2024
534f856
[InstCombine] Don't preserve context across div
nikic Jun 17, 2024
954cb5f
[mlir][Target] Improve ROCDL gpu serialization API (#95456)
fabianmcg Jun 17, 2024
4bf160e
[clang][Interp] Implement Complex-complex multiplication (#94891)
tbaederr Jun 17, 2024
57b8be4
Revert [mlir][Target] Improve ROCDL gpu serialization API (#95790)
fabianmcg Jun 17, 2024
a1bdb01
[VectorCombine] Change shuffleToIdentity to use Use. NFC
davemgreen Jun 17, 2024
4cf1a19
Reapply "AMDGPU: Handle legal v2f16/v2bf16 atomicrmw fadd for global/…
arsenm Jun 16, 2024
c659e3a
[TableGen][Docs] Fix `!range` markup (#95540)
pfusik Jun 17, 2024
d3da134
[RISCV] Add coverage for vsetvli insertion at O0 [nfc]
preames Jun 17, 2024
f065758
[mlir][spirv] Reland integration test for `vector.deinterleave` (#95800)
angelz913 Jun 17, 2024
c11677e
[LLD][COFF] Support finding pdb files from outputpath (#94153)
GkvJwa Jun 17, 2024
964c92d
[RISCV][InsertVSETVLI] Eliminate the AVLIsIgnored state (#94658)
preames Jun 17, 2024
0851d7b
[clang][analyzer] use unqualified canonical type during merging equiv…
HerrCai0907 Jun 17, 2024
8fe376f
[llvm] Fix incorrect usage of `LIBXML2_INCLUDE_DIRS` in the Windows r…
aganea Jun 17, 2024
13c6638
[lldb] Add packaging to testing requirements.txt (#95806)
DavidSpickett Jun 17, 2024
b6476e5
[LV] Retain branch in middle block when scalar epilogue is needed (NFC)
fhahn Jun 17, 2024
fae31e2
[DebugInfo] Change handling of structured bindings of bitfields (#94…
john-brawn-arm Jun 17, 2024
85f4593
[flang] Add a REDUCE clause to each nested loop (#95555)
khaki3 Jun 17, 2024
3380644
[lldb] Remove SupportFile::Update and use the original Checksum (#95623)
JDevlieghere Jun 17, 2024
e577f96
[AMDGPU] Move FeatureMaxHardClauseLength32 into FeatureISAVersion12. …
jayfoad Jun 17, 2024
5914a56
[GitHub][workflows] Use latest clang-format version 18.1.7 (#95757)
owenca Jun 17, 2024
d1a4f0c
[AArch64] Lower extending sitofp using tbl (#92528)
momchil-velikov Jun 17, 2024
fe3f8ad
[X86] getIntrinsicInstrCost - begin generalizing BSWAP load/store-fol…
RKSimon Jun 17, 2024
7e3507e
[DAG] visitAVG - avoid duplication in the avg(ext(x), ext(y)) -> ext(…
RKSimon Jun 17, 2024
a1994ae
[lldb] More reliably detect a virtual environment
JDevlieghere Jun 17, 2024
2ebe479
[Clang] Disallow non-lvalue values in constant expressions to prevent…
a-tarasyuk Jun 17, 2024
4447e25
[NFC] Refactor `[[nodiscard]]` test to not use macros and run under `…
MitalAshok Jun 17, 2024
3ad31e1
[Clang] Introduce `CXXTypeidExpr::hasNullCheck` (#95718)
MitalAshok Jun 17, 2024
a4b44c0
[InstCombine] Canonicalize `icmp ult (add X, C2), C` expressions
antoniofrighetto Jun 15, 2024
3a2e442
[mlir][sparse] implement lowering rules for IterateOp. (#95286)
Jun 17, 2024
21ba91c
[SamplePGO] Add a cutoff for number of profile matching anchors (#95542)
amharc Jun 17, 2024
75073a8
[AutoBump] Merge with 21ba91c4 (Jun 17)
mgehre-amd Sep 12, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/pr-code-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
- name: Install clang-format
uses: aminya/setup-cpp@v1
with:
clangformat: 18.1.1
clangformat: 18.1.7

- name: Setup Python env
uses: actions/setup-python@v5
Expand Down
5 changes: 5 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ Resolutions to C++ Defect Reports
- Clang now requires a template argument list after a template keyword.
(`CWG96: Syntactic disambiguation using the template keyword <https://cplusplus.github.io/CWG/issues/96.html>`_).

- Clang now considers ``noexcept(typeid(expr))`` more carefully, instead of always assuming that ``std::bad_typeid`` can be thrown.
(`CWG2191: Incorrect result for noexcept(typeid(v)) <https://cplusplus.github.io/CWG/issues/2191.html>`_).

C Language Changes
------------------

Expand Down Expand Up @@ -859,6 +862,8 @@ Bug Fixes to C++ Support
(#GH88081), (#GH89496), (#GH90669) and (#GH91633).
- Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368).
- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849)
- Fixed a failed assertion when attempting to convert an integer representing the difference
between the addresses of two labels (a GNU extension) to a pointer within a constant expression. (#GH95366).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,10 @@ class CXXTypeidExpr : public Expr {
reinterpret_cast<Stmt **>(&const_cast<CXXTypeidExpr *>(this)->Operand);
return const_child_range(begin, begin + 1);
}

/// Whether this is of a form like "typeid(*ptr)" that can throw a
/// std::bad_typeid if a pointer is a null pointer ([expr.typeid]p2)
bool hasNullCheck() const;
};

/// A member reference to an MSPropertyDecl.
Expand Down
9 changes: 6 additions & 3 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -7036,6 +7036,12 @@ def as_secure_log_file : Separate<["-"], "as-secure-log-file">,

} // let Visibility = [CC1Option, CC1AsOption]

let Visibility = [CC1Option, FC1Option] in {
def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">,
HelpText<"Link and internalize needed symbols from the given bitcode file "
"before performing optimizations.">;
} // let Visibility = [CC1Option, FC1Option]

let Visibility = [CC1Option] in {

def llvm_verify_each : Flag<["-"], "llvm-verify-each">,
Expand Down Expand Up @@ -7138,9 +7144,6 @@ defm constructor_aliases : BoolMOption<"constructor-aliases",
" emitting complete constructors and destructors as aliases when possible">>;
def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">,
HelpText<"Link the given bitcode file before performing optimizations.">;
def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">,
HelpText<"Link and internalize needed symbols from the given bitcode file "
"before performing optimizations.">;
defm link_builtin_bitcode_postopt: BoolMOption<"link-builtin-bitcode-postopt",
CodeGenOpts<"LinkBitcodePostopt">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption], "Link builtin bitcodes after the "
Expand Down
16 changes: 12 additions & 4 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3769,10 +3769,18 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
break;
}

case CXXTypeidExprClass:
// typeid might throw if its subexpression is potentially-evaluated, so has
// side-effects in that case whether or not its subexpression does.
return cast<CXXTypeidExpr>(this)->isPotentiallyEvaluated();
case CXXTypeidExprClass: {
const auto *TE = cast<CXXTypeidExpr>(this);
if (!TE->isPotentiallyEvaluated())
return false;

// If this type id expression can throw because of a null pointer, that is a
// side-effect independent of if the operand has a side-effect
if (IncludePossibleEffects && TE->hasNullCheck())
return true;

break;
}

case CXXConstructExprClass:
case CXXTemporaryObjectExprClass: {
Expand Down
47 changes: 47 additions & 0 deletions clang/lib/AST/ExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,53 @@ QualType CXXTypeidExpr::getTypeOperand(ASTContext &Context) const {
Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), Quals);
}

static bool isGLValueFromPointerDeref(const Expr *E) {
E = E->IgnoreParens();

if (const auto *CE = dyn_cast<CastExpr>(E)) {
if (!CE->getSubExpr()->isGLValue())
return false;
return isGLValueFromPointerDeref(CE->getSubExpr());
}

if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
return isGLValueFromPointerDeref(OVE->getSourceExpr());

if (const auto *BO = dyn_cast<BinaryOperator>(E))
if (BO->getOpcode() == BO_Comma)
return isGLValueFromPointerDeref(BO->getRHS());

if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(E))
return isGLValueFromPointerDeref(ACO->getTrueExpr()) ||
isGLValueFromPointerDeref(ACO->getFalseExpr());

// C++11 [expr.sub]p1:
// The expression E1[E2] is identical (by definition) to *((E1)+(E2))
if (isa<ArraySubscriptExpr>(E))
return true;

if (const auto *UO = dyn_cast<UnaryOperator>(E))
if (UO->getOpcode() == UO_Deref)
return true;

return false;
}

bool CXXTypeidExpr::hasNullCheck() const {
if (!isPotentiallyEvaluated())
return false;

// C++ [expr.typeid]p2:
// If the glvalue expression is obtained by applying the unary * operator to
// a pointer and the pointer is a null pointer value, the typeid expression
// throws the std::bad_typeid exception.
//
// However, this paragraph's intent is not clear. We choose a very generous
// interpretation which implores us to consider comma operators, conditional
// operators, parentheses and other such constructs.
return isGLValueFromPointerDeref(getExprOperand());
}

QualType CXXUuidofExpr::getTypeOperand(ASTContext &Context) const {
assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
Qualifiers Quals;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/AST/ExprConstShared.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#ifndef LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
#define LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H

namespace llvm {
class APFloat;
}
namespace clang {
class QualType;
class LangOptions;
Expand Down Expand Up @@ -56,4 +59,8 @@ enum class GCCTypeClass {
GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
const LangOptions &LangOpts);

void HandleComplexComplexMul(llvm::APFloat A, llvm::APFloat B, llvm::APFloat C,
llvm::APFloat D, llvm::APFloat &ResR,
llvm::APFloat &ResI);

#endif
113 changes: 64 additions & 49 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9325,6 +9325,13 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
Result.IsNullPtr = false;
return true;
} else {
// In rare instances, the value isn't an lvalue.
// For example, when the value is the difference between the addresses of
// two labels. We reject that as a constant expression because we can't
// compute a valid offset to convert into a pointer.
if (!Value.isLValue())
return false;

// Cast is of an lvalue, no need to change value.
Result.setFrom(Info.Ctx, Value);
return true;
Expand Down Expand Up @@ -15126,6 +15133,62 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
llvm_unreachable("unknown cast resulting in complex value");
}

void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D,
APFloat &ResR, APFloat &ResI) {
// This is an implementation of complex multiplication according to the
// constraints laid out in C11 Annex G. The implementation uses the
// following naming scheme:
// (a + ib) * (c + id)

APFloat AC = A * C;
APFloat BD = B * D;
APFloat AD = A * D;
APFloat BC = B * C;
ResR = AC - BD;
ResI = AD + BC;
if (ResR.isNaN() && ResI.isNaN()) {
bool Recalc = false;
if (A.isInfinity() || B.isInfinity()) {
A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
A);
B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
B);
if (C.isNaN())
C = APFloat::copySign(APFloat(C.getSemantics()), C);
if (D.isNaN())
D = APFloat::copySign(APFloat(D.getSemantics()), D);
Recalc = true;
}
if (C.isInfinity() || D.isInfinity()) {
C = APFloat::copySign(APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0),
C);
D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
D);
if (A.isNaN())
A = APFloat::copySign(APFloat(A.getSemantics()), A);
if (B.isNaN())
B = APFloat::copySign(APFloat(B.getSemantics()), B);
Recalc = true;
}
if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
BC.isInfinity())) {
if (A.isNaN())
A = APFloat::copySign(APFloat(A.getSemantics()), A);
if (B.isNaN())
B = APFloat::copySign(APFloat(B.getSemantics()), B);
if (C.isNaN())
C = APFloat::copySign(APFloat(C.getSemantics()), C);
if (D.isNaN())
D = APFloat::copySign(APFloat(D.getSemantics()), D);
Recalc = true;
}
if (Recalc) {
ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
}
}
}

bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
Expand Down Expand Up @@ -15225,55 +15288,7 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
!handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B))
return false;
} else {
// In the fully general case, we need to handle NaNs and infinities
// robustly.
APFloat AC = A * C;
APFloat BD = B * D;
APFloat AD = A * D;
APFloat BC = B * C;
ResR = AC - BD;
ResI = AD + BC;
if (ResR.isNaN() && ResI.isNaN()) {
bool Recalc = false;
if (A.isInfinity() || B.isInfinity()) {
A = APFloat::copySign(
APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
B = APFloat::copySign(
APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
if (C.isNaN())
C = APFloat::copySign(APFloat(C.getSemantics()), C);
if (D.isNaN())
D = APFloat::copySign(APFloat(D.getSemantics()), D);
Recalc = true;
}
if (C.isInfinity() || D.isInfinity()) {
C = APFloat::copySign(
APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
D = APFloat::copySign(
APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
if (A.isNaN())
A = APFloat::copySign(APFloat(A.getSemantics()), A);
if (B.isNaN())
B = APFloat::copySign(APFloat(B.getSemantics()), B);
Recalc = true;
}
if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
AD.isInfinity() || BC.isInfinity())) {
if (A.isNaN())
A = APFloat::copySign(APFloat(A.getSemantics()), A);
if (B.isNaN())
B = APFloat::copySign(APFloat(B.getSemantics()), B);
if (C.isNaN())
C = APFloat::copySign(APFloat(C.getSemantics()), C);
if (D.isNaN())
D = APFloat::copySign(APFloat(D.getSemantics()), D);
Recalc = true;
}
if (Recalc) {
ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
}
}
HandleComplexComplexMul(A, B, C, D, ResR, ResI);
}
} else {
ComplexValue LHS = Result;
Expand Down
55 changes: 45 additions & 10 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,22 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
if (const auto *AT = RHSType->getAs<AtomicType>())
RHSType = AT->getValueType();

// For ComplexComplex Mul, we have special ops to make their implementation
// easier.
BinaryOperatorKind Op = E->getOpcode();
if (Op == BO_Mul && LHSType->isAnyComplexType() &&
RHSType->isAnyComplexType()) {
assert(classifyPrim(LHSType->getAs<ComplexType>()->getElementType()) ==
classifyPrim(RHSType->getAs<ComplexType>()->getElementType()));
PrimType ElemT =
classifyPrim(LHSType->getAs<ComplexType>()->getElementType());
if (!this->visit(LHS))
return false;
if (!this->visit(RHS))
return false;
return this->emitMulc(ElemT, E);
}

// Evaluate LHS and save value to LHSOffset.
bool LHSIsComplex;
unsigned LHSOffset;
Expand Down Expand Up @@ -919,38 +935,37 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
// For both LHS and RHS, either load the value from the complex pointer, or
// directly from the local variable. For index 1 (i.e. the imaginary part),
// just load 0 and do the operation anyway.
auto loadComplexValue = [this](bool IsComplex, unsigned ElemIndex,
unsigned Offset, const Expr *E) -> bool {
auto loadComplexValue = [this](bool IsComplex, bool LoadZero,
unsigned ElemIndex, unsigned Offset,
const Expr *E) -> bool {
if (IsComplex) {
if (!this->emitGetLocal(PT_Ptr, Offset, E))
return false;
return this->emitArrayElemPop(classifyComplexElementType(E->getType()),
ElemIndex, E);
}
if (ElemIndex == 0)
if (ElemIndex == 0 || !LoadZero)
return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);
return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(),
E);
};

// Now we can get pointers to the LHS and RHS from the offsets above.
BinaryOperatorKind Op = E->getOpcode();
for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
// Result pointer for the store later.
if (!this->DiscardResult) {
if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
return false;
}

if (!loadComplexValue(LHSIsComplex, ElemIndex, LHSOffset, LHS))
return false;

if (!loadComplexValue(RHSIsComplex, ElemIndex, RHSOffset, RHS))
return false;

// The actual operation.
switch (Op) {
case BO_Add:
if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
return false;

if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
return false;
if (ResultElemT == PT_Float) {
if (!this->emitAddf(getRoundingMode(E), E))
return false;
Expand All @@ -960,6 +975,11 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
}
break;
case BO_Sub:
if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
return false;

if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
return false;
if (ResultElemT == PT_Float) {
if (!this->emitSubf(getRoundingMode(E), E))
return false;
Expand All @@ -968,6 +988,21 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
return false;
}
break;
case BO_Mul:
if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
return false;

if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
return false;

if (ResultElemT == PT_Float) {
if (!this->emitMulf(getRoundingMode(E), E))
return false;
} else {
if (!this->emitMul(ResultElemT, E))
return false;
}
break;

default:
return false;
Expand Down
Loading