Skip to content

Commit ffd7301

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:f0d60170cc50 into amd-gfx:9ec2e21f19dd
Local branch amd-gfx 9ec2e21 Merged main:5b5ef254a341 into amd-gfx:df6887bb62f3 Remote branch main f0d6017 [clang][bytecode] Check memove/memcpy for available elements (llvm#121383)
2 parents 9ec2e21 + f0d6017 commit ffd7301

File tree

8 files changed

+86
-19
lines changed

8 files changed

+86
-19
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "clang/Basic/Builtins.h"
1818
#include "clang/Basic/TargetBuiltins.h"
1919
#include "clang/Basic/TargetInfo.h"
20+
#include "llvm/ADT/StringExtras.h"
2021
#include "llvm/Support/SipHash.h"
2122

2223
namespace clang {
@@ -1837,6 +1838,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18371838
assert(Call->getNumArgs() == 3);
18381839
unsigned ID = Func->getBuiltinID();
18391840
Pointer DestPtr = getParam<Pointer>(Frame, 0);
1841+
const ASTContext &ASTCtx = S.getASTContext();
18401842
const Pointer &SrcPtr = getParam<Pointer>(Frame, 1);
18411843
const APSInt &Size =
18421844
peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2)));
@@ -1857,34 +1859,55 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18571859
Pointer DiagPtr = (SrcPtr.isZero() ? SrcPtr : DestPtr);
18581860
S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null)
18591861
<< /*IsMove=*/Move << /*IsWchar=*/false << !SrcPtr.isZero()
1860-
<< DiagPtr.toDiagnosticString(S.getASTContext());
1862+
<< DiagPtr.toDiagnosticString(ASTCtx);
18611863
return false;
18621864
}
18631865

1864-
QualType ElemType;
1865-
if (DestPtr.getFieldDesc()->isArray())
1866-
ElemType = DestPtr.getFieldDesc()->getElemQualType();
1867-
else
1868-
ElemType = DestPtr.getType();
1866+
QualType DestElemType;
1867+
size_t RemainingDestElems;
1868+
if (DestPtr.getFieldDesc()->isArray()) {
1869+
DestElemType = DestPtr.getFieldDesc()->getElemQualType();
1870+
RemainingDestElems = (DestPtr.getNumElems() - DestPtr.getIndex());
1871+
} else {
1872+
DestElemType = DestPtr.getType();
1873+
RemainingDestElems = 1;
1874+
}
1875+
unsigned DestElemSize = ASTCtx.getTypeSizeInChars(DestElemType).getQuantity();
18691876

1870-
unsigned ElemSize =
1871-
S.getASTContext().getTypeSizeInChars(ElemType).getQuantity();
1872-
if (Size.urem(ElemSize) != 0) {
1877+
if (Size.urem(DestElemSize) != 0) {
18731878
S.FFDiag(S.Current->getSource(OpPC),
18741879
diag::note_constexpr_memcpy_unsupported)
1875-
<< Move << /*IsWchar=*/false << 0 << ElemType << Size << ElemSize;
1880+
<< Move << /*IsWchar=*/false << 0 << DestElemType << Size
1881+
<< DestElemSize;
18761882
return false;
18771883
}
18781884

18791885
QualType SrcElemType;
1880-
if (SrcPtr.getFieldDesc()->isArray())
1886+
size_t RemainingSrcElems;
1887+
if (SrcPtr.getFieldDesc()->isArray()) {
18811888
SrcElemType = SrcPtr.getFieldDesc()->getElemQualType();
1882-
else
1889+
RemainingSrcElems = (SrcPtr.getNumElems() - SrcPtr.getIndex());
1890+
} else {
18831891
SrcElemType = SrcPtr.getType();
1892+
RemainingSrcElems = 1;
1893+
}
1894+
unsigned SrcElemSize = ASTCtx.getTypeSizeInChars(SrcElemType).getQuantity();
18841895

1885-
if (!S.getASTContext().hasSameUnqualifiedType(ElemType, SrcElemType)) {
1896+
if (!ASTCtx.hasSameUnqualifiedType(DestElemType, SrcElemType)) {
18861897
S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_type_pun)
1887-
<< Move << SrcElemType << ElemType;
1898+
<< Move << SrcElemType << DestElemType;
1899+
return false;
1900+
}
1901+
1902+
// Check if we have enough elements to read from and write to/
1903+
size_t RemainingDestBytes = RemainingDestElems * DestElemSize;
1904+
size_t RemainingSrcBytes = RemainingSrcElems * SrcElemSize;
1905+
if (Size.ugt(RemainingDestBytes) || Size.ugt(RemainingSrcBytes)) {
1906+
APInt N = Size.udiv(DestElemSize);
1907+
S.FFDiag(S.Current->getSource(OpPC),
1908+
diag::note_constexpr_memcpy_unsupported)
1909+
<< Move << /*IsWChar*/ false << (Size.ugt(RemainingSrcBytes) ? 1 : 2)
1910+
<< DestElemType << toString(N, 10, /*Signed=*/false);
18881911
return false;
18891912
}
18901913

@@ -1905,7 +1928,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
19051928
// As a last resort, reject dummy pointers.
19061929
if (DestPtr.isDummy() || SrcPtr.isDummy())
19071930
return false;
1908-
assert(Size.getZExtValue() % ElemSize == 0);
1931+
assert(Size.getZExtValue() % DestElemSize == 0);
19091932
if (!DoMemcpy(S, OpPC, SrcPtr, DestPtr, Bytes(Size.getZExtValue()).toBits()))
19101933
return false;
19111934

clang/test/AST/ByteCode/builtin-functions.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,15 @@ namespace BuiltinMemcpy {
12441244
}
12451245
static_assert(cpyptr());
12461246

1247+
#ifndef __AVR__
1248+
constexpr int test_memmove(int a, int b, int n) {
1249+
int arr[4] = {1, 2, 3, 4};
1250+
__builtin_memmove(arr + a, arr + b, n); // both-note {{destination is not a contiguous array of at least 3 elements of type 'int'}}
1251+
return result(arr);
1252+
}
1253+
static_assert(test_memmove(2, 0, 12) == 4234); // both-error {{constant}} \
1254+
// both-note {{in call}}
1255+
#endif
12471256
}
12481257

12491258
namespace Memcmp {

llvm/include/llvm/Config/llvm-config.h.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
/* Indicate that this is LLVM compiled from the amd-gfx branch. */
1818
#define LLVM_HAVE_BRANCH_AMD_GFX
19-
#define LLVM_MAIN_REVISION 522537
19+
#define LLVM_MAIN_REVISION 522541
2020

2121
/* Define if LLVM_ENABLE_DUMP is enabled */
2222
#cmakedefine LLVM_ENABLE_DUMP

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15765,6 +15765,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1576515765
// original header.
1576615766
// TODO: share this logic with isLoopEntryGuardedByCond.
1576715767
unsigned NumCollectedConditions = 0;
15768+
VisitedBlocks.insert(Block);
1576815769
std::pair<const BasicBlock *, const BasicBlock *> Pair(Pred, Block);
1576915770
for (; Pair.first;
1577015771
Pair = SE.getPredecessorWithUniqueSuccessorForBB(Pair.first)) {

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ using namespace llvm::PatternMatch;
3535
static cl::opt<bool> EnableFalkorHWPFUnrollFix("enable-falkor-hwpf-unroll-fix",
3636
cl::init(true), cl::Hidden);
3737

38+
static cl::opt<bool> SVEPreferFixedOverScalableIfEqualCost(
39+
"sve-prefer-fixed-over-scalable-if-equal", cl::Hidden);
40+
3841
static cl::opt<unsigned> SVEGatherOverhead("sve-gather-overhead", cl::init(10),
3942
cl::Hidden);
4043

@@ -4919,6 +4922,12 @@ static bool containsDecreasingPointers(Loop *TheLoop,
49194922
return false;
49204923
}
49214924

4925+
bool AArch64TTIImpl::preferFixedOverScalableIfEqualCost() const {
4926+
if (SVEPreferFixedOverScalableIfEqualCost.getNumOccurrences())
4927+
return SVEPreferFixedOverScalableIfEqualCost;
4928+
return ST->useFixedOverScalableIfEqualCost();
4929+
}
4930+
49224931
unsigned AArch64TTIImpl::getEpilogueVectorizationMinVF() const {
49234932
return ST->getEpilogueVectorizationMinVF();
49244933
}

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,7 @@ class AArch64TTIImpl : public BasicTTIImplBase<AArch64TTIImpl> {
387387
return TailFoldingStyle::DataWithoutLaneMask;
388388
}
389389

390-
bool preferFixedOverScalableIfEqualCost() const {
391-
return ST->useFixedOverScalableIfEqualCost();
392-
}
390+
bool preferFixedOverScalableIfEqualCost() const;
393391

394392
unsigned getEpilogueVectorizationMinVF() const;
395393

llvm/lib/Target/RISCV/RISCVSchedule.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ def : ReadAdvance<ReadFCvtF16ToI32, 0>;
237237
def : ReadAdvance<ReadFDiv16, 0>;
238238
def : ReadAdvance<ReadFCmp16, 0>;
239239
def : ReadAdvance<ReadFMA16, 0>;
240+
def : ReadAdvance<ReadFMA16Addend, 0>;
240241
def : ReadAdvance<ReadFMinMax16, 0>;
241242
def : ReadAdvance<ReadFMul16, 0>;
242243
def : ReadAdvance<ReadFSGNJ16, 0>;

llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,29 @@ inner.header:
310310
exit:
311311
ret void
312312
}
313+
314+
; Checks correct traversal for loops without a unique predecessor
315+
; outside the loop.
316+
define void @pr120615() {
317+
; CHECK-LABEL: pr120615
318+
; CHECK-NEXT: Determining loop execution counts for: @pr120615
319+
; CHECK-NEXT: Loop %header: backedge-taken count is i32 0
320+
; CHECK-NEXT: Loop %header: constant max backedge-taken count is i32 0
321+
; CHECK-NEXT: Loop %header: symbolic max backedge-taken count is i32 0
322+
; CHECK-NEXT: Loop %header: Trip multiple is 1
323+
entry:
324+
br label %header
325+
326+
bb:
327+
br label %header
328+
329+
header:
330+
%0 = phi i32 [ %1, %header ], [ 0, %bb ], [ 0, %entry ]
331+
%1 = add i32 %0, 1
332+
%icmp = icmp slt i32 %0, 0
333+
br i1 %icmp, label %header, label %exit
334+
335+
exit:
336+
ret void
337+
338+
}

0 commit comments

Comments
 (0)