From 4746877c2716224dc87c69750bdd0df95b6d5b16 Mon Sep 17 00:00:00 2001
From: Aaron Ballman
Date: Mon, 1 Apr 2024 13:51:47 -0400
Subject: [PATCH 001/442] [C99] Claim conformance to WG14 N570
---
clang/test/C/C99/n570.c | 31 +++++++++++++++++++++++++++++++
clang/www/c_status.html | 2 +-
2 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 clang/test/C/C99/n570.c
diff --git a/clang/test/C/C99/n570.c b/clang/test/C/C99/n570.c
new file mode 100644
index 000000000000..31c09224e618
--- /dev/null
+++ b/clang/test/C/C99/n570.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -verify -std=c99 %s
+// RUN: %clang_cc1 -E -std=c99 %s | FileCheck %s
+// expected-no-diagnostics
+
+/* WG14 N570: Yes
+ * Empty macro arguments
+ *
+ * NB: the original paper is not available online anywhere, so the test
+ * coverage is coming from what could be gleaned from the C99 rationale
+ * document. In C89, it was UB to pass no arguments to a function-like macro,
+ * and that's now supported in C99.
+ */
+
+#define TEN 10
+#define U u
+#define I // expands into no preprocessing tokens
+#define L L
+#define glue(a, b) a ## b
+#define xglue(a, b) glue(a, b)
+
+const unsigned u = xglue(TEN, U);
+const int i = xglue(TEN, I);
+const long l = xglue(TEN, L);
+
+// CHECK: const unsigned u = 10u;
+// CHECK-NEXT: const int i = 10;
+// CHECK-NEXT: const long l = 10L;
+
+_Static_assert(u == 10U, "");
+_Static_assert(i == 10, "");
+_Static_assert(l == 10L, "");
diff --git a/clang/www/c_status.html b/clang/www/c_status.html
index 028234a8961d..123897593e5d 100644
--- a/clang/www/c_status.html
+++ b/clang/www/c_status.html
@@ -300,7 +300,7 @@ conformance.
| empty macro arguments |
N570 |
- Unknown |
+ Yes |
| new structure type compatibility (tag compatibility) |
--
GitLab
From 5ff2773d4e606ac57750f1fc2aa4dc49b8dbede1 Mon Sep 17 00:00:00 2001
From: Russell Greene
Date: Mon, 1 Apr 2024 12:15:24 -0600
Subject: [PATCH 002/442] [clang-cl] Allow a colon after /Fo option (#87209)
Modeled after
https://github.com/llvm/llvm-project/commit/8513a681f7d8d1188706762e712168aebc3119dd#
According to
https://learn.microsoft.com/en-us/cpp/build/reference/fo-object-file-name?view=msvc-170,
`/Fo` accepts a trailing-colon variant. This is also tested in practice.
This allows clang-cl to parse this.
I just copied one of the existing tests, let me know if this is not the
best way to do this. I tested that the test does not pass beofre the
Options.td change, and that it does after.
See also #46065
---
clang/include/clang/Driver/Options.td | 1 +
clang/test/Driver/cl-outputs.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 04eb87f0d5d1..f5289fb00c89 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -8313,6 +8313,7 @@ def _SLASH_Fi : CLCompileJoined<"Fi">,
def _SLASH_Fo : CLCompileJoined<"Fo">,
HelpText<"Set output object file (with /c)">,
MetaVarName<"">;
+def _SLASH_Fo_COLON : CLCompileJoined<"Fo:">, Alias<_SLASH_Fo>;
def _SLASH_guard : CLJoined<"guard:">,
HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks. "
"Enable EH Continuation Guard with /guard:ehcont">;
diff --git a/clang/test/Driver/cl-outputs.c b/clang/test/Driver/cl-outputs.c
index 07ff43642a62..4d58f0fb548b 100644
--- a/clang/test/Driver/cl-outputs.c
+++ b/clang/test/Driver/cl-outputs.c
@@ -301,5 +301,8 @@
// RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Foa.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH1 %s
// RELATIVE_OBJPATH1: "-object-file-name=a.obj"
+// RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fo:a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH1_COLON %s
+// RELATIVE_OBJPATH1_COLON: "-object-file-name=a.obj"
+
// RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fofoo/a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH2 %s
// RELATIVE_OBJPATH2: "-object-file-name=foo\\a.obj"
--
GitLab
From 6634c3e9377abf88c08bb065fb55aa15cda4c248 Mon Sep 17 00:00:00 2001
From: Kai Nacke
Date: Mon, 1 Apr 2024 14:20:41 -0400
Subject: [PATCH 003/442] [GOFF] Wrap debug output with LLVM_DEBUG (#87252)
The content of a GOFF record is always dumped if NDEBUG is not defined,
which produces rather confusing output. This changes wrap the dumping
code in LLVM_DEBUG, so the dump is only done when debug output of this
module is requested.
---
llvm/lib/Object/GOFFObjectFile.cpp | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Object/GOFFObjectFile.cpp b/llvm/lib/Object/GOFFObjectFile.cpp
index 76a13559ebfe..d3dfd5d1540c 100644
--- a/llvm/lib/Object/GOFFObjectFile.cpp
+++ b/llvm/lib/Object/GOFFObjectFile.cpp
@@ -104,16 +104,13 @@ GOFFObjectFile::GOFFObjectFile(MemoryBufferRef Object, Error &Err)
PrevContinuationBits = I[1] & 0x03;
continue;
}
-
-#ifndef NDEBUG
- for (size_t J = 0; J < GOFF::RecordLength; ++J) {
+ LLVM_DEBUG(for (size_t J = 0; J < GOFF::RecordLength; ++J) {
const uint8_t *P = I + J;
if (J % 8 == 0)
dbgs() << " ";
-
dbgs() << format("%02hhX", *P);
- }
-#endif
+ });
+
switch (RecordType) {
case GOFF::RT_ESD: {
// Save ESD record.
--
GitLab
From b8ead2198f27924f91b90b6c104c1234ccc8972e Mon Sep 17 00:00:00 2001
From: Gulfem Savrun Yeniceri
Date: Mon, 1 Apr 2024 18:25:02 +0000
Subject: [PATCH 004/442] Revert "[CodeGen] Fix register pressure computation
in MachinePipeliner (#87030)"
This reverts commit a4dec9d6bc67c4d8fbd4a4f54ffaa0399def9627
because the test failed in the following builder:
https://luci-milo.appspot.com/ui/p/fuchsia/builders/prod/clang-linux-x64/b8751864477467126481/overview
---
llvm/lib/CodeGen/MachinePipeliner.cpp | 2 +-
llvm/test/CodeGen/AArch64/sms-regpress.mir | 158 -----------------
llvm/test/CodeGen/PowerPC/sms-regpress.mir | 186 ++++++++++++++++++---
3 files changed, 166 insertions(+), 180 deletions(-)
delete mode 100644 llvm/test/CodeGen/AArch64/sms-regpress.mir
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index b9c6765be445..eb42a78603d4 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -1268,7 +1268,7 @@ private:
// Calculate the upper limit of each pressure set
void computePressureSetLimit(const RegisterClassInfo &RCI) {
for (unsigned PSet = 0; PSet < PSetNum; PSet++)
- PressureSetLimit[PSet] = TRI->getRegPressureSetLimit(MF, PSet);
+ PressureSetLimit[PSet] = RCI.getRegPressureSetLimit(PSet);
// We assume fixed registers, such as stack pointer, are already in use.
// Therefore subtracting the weight of the fixed registers from the limit of
diff --git a/llvm/test/CodeGen/AArch64/sms-regpress.mir b/llvm/test/CodeGen/AArch64/sms-regpress.mir
deleted file mode 100644
index ad98d5c6124f..000000000000
--- a/llvm/test/CodeGen/AArch64/sms-regpress.mir
+++ /dev/null
@@ -1,158 +0,0 @@
-# RUN: llc --verify-machineinstrs -mtriple=aarch64 -o - %s -run-pass pipeliner -aarch64-enable-pipeliner -pipeliner-max-mii=40 -pipeliner-register-pressure -pipeliner-ii-search-range=30 -debug-only=pipeliner 2>&1 | FileCheck %s
-
-# Check that if the register pressure is too high, the schedule is rejected, II is incremented, and scheduling continues.
-# The specific value of II is not important.
-
-# CHECK: {{^ *}}Try to schedule with {{[0-9]+$}}
-# CHECK: {{^ *}}Rejected the schedule because of too high register pressure{{$}}
-# CHECK: {{^ *}}Try to schedule with {{[0-9]+$}}
-# CHECK: {{^ *}}Schedule Found? 1 (II={{[0-9]+}}){{$}}
-
---- |
- target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
-
- define dso_local double @kernel(ptr nocapture noundef readonly %a, ptr nocapture noundef readonly %b, i32 noundef %n) local_unnamed_addr {
- entry:
- %0 = load double, ptr %a, align 8
- %arrayidx1 = getelementptr inbounds i8, ptr %a, i64 8
- %1 = load double, ptr %arrayidx1, align 8
- %cmp133 = icmp sgt i32 %n, 0
- br i1 %cmp133, label %for.body.preheader, label %for.cond.cleanup
-
- for.body.preheader: ; preds = %entry
- %wide.trip.count = zext nneg i32 %n to i64
- br label %for.body
-
- for.cond.cleanup: ; preds = %for.body, %entry
- %res.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %add54, %for.body ]
- ret double %res.0.lcssa
-
- for.body: ; preds = %for.body.preheader, %for.body
- %lsr.iv137 = phi i64 [ %wide.trip.count, %for.body.preheader ], [ %lsr.iv.next, %for.body ]
- %lsr.iv = phi ptr [ %b, %for.body.preheader ], [ %scevgep, %for.body ]
- %res.0135 = phi double [ 0.000000e+00, %for.body.preheader ], [ %add54, %for.body ]
- %2 = load double, ptr %lsr.iv, align 8
- %3 = tail call double @llvm.fmuladd.f64(double %0, double %2, double %0)
- %4 = tail call double @llvm.fmuladd.f64(double %3, double %2, double %3)
- %5 = tail call double @llvm.fmuladd.f64(double %4, double %2, double %4)
- %6 = tail call double @llvm.fmuladd.f64(double %5, double %2, double %5)
- %7 = tail call double @llvm.fmuladd.f64(double %6, double %2, double %6)
- %8 = tail call double @llvm.fmuladd.f64(double %7, double %2, double %7)
- %9 = tail call double @llvm.fmuladd.f64(double %8, double %2, double %8)
- %10 = tail call double @llvm.fmuladd.f64(double %9, double %2, double %9)
- %11 = tail call double @llvm.fmuladd.f64(double %10, double %2, double %10)
- %12 = tail call double @llvm.fmuladd.f64(double %11, double %2, double %11)
- %13 = tail call double @llvm.fmuladd.f64(double %12, double %2, double %12)
- %14 = tail call double @llvm.fmuladd.f64(double %13, double %2, double %13)
- %15 = tail call double @llvm.fmuladd.f64(double %14, double %2, double %14)
- %16 = tail call double @llvm.fmuladd.f64(double %15, double %2, double %15)
- %17 = tail call double @llvm.fmuladd.f64(double %16, double %2, double %16)
- %18 = tail call double @llvm.fmuladd.f64(double %17, double %2, double %17)
- %add = fadd double %17, %18
- %19 = tail call double @llvm.fmuladd.f64(double %18, double %2, double %add)
- %add35 = fadd double %10, %19
- %20 = tail call double @llvm.fmuladd.f64(double %3, double %2, double %add35)
- %add38 = fadd double %11, %20
- %21 = tail call double @llvm.fmuladd.f64(double %4, double %2, double %add38)
- %add41 = fadd double %12, %21
- %22 = tail call double @llvm.fmuladd.f64(double %5, double %2, double %add41)
- %add44 = fadd double %14, %15
- %add45 = fadd double %13, %add44
- %add46 = fadd double %add45, %22
- %23 = tail call double @llvm.fmuladd.f64(double %6, double %2, double %add46)
- %mul = fmul double %2, %7
- %mul51 = fmul double %1, %mul
- %24 = tail call double @llvm.fmuladd.f64(double %mul51, double %9, double %23)
- %25 = tail call double @llvm.fmuladd.f64(double %8, double %1, double %24)
- %add54 = fadd double %res.0135, %25
- %scevgep = getelementptr i8, ptr %lsr.iv, i64 8
- %lsr.iv.next = add nsw i64 %lsr.iv137, -1
- %exitcond.not = icmp eq i64 %lsr.iv.next, 0
- br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
- }
-
- declare double @llvm.fmuladd.f64(double, double, double)
-
-...
----
-name: kernel
-tracksRegLiveness: true
-liveins:
- - { reg: '$x0', virtual-reg: '%10' }
- - { reg: '$x1', virtual-reg: '%11' }
- - { reg: '$w2', virtual-reg: '%12' }
-body: |
- bb.0.entry:
- successors: %bb.1, %bb.4
- liveins: $x0, $x1, $w2
-
- %12:gpr32common = COPY $w2
- %11:gpr64 = COPY $x1
- %10:gpr64common = COPY $x0
- dead $wzr = SUBSWri %12, 1, 0, implicit-def $nzcv
- Bcc 10, %bb.1, implicit $nzcv
-
- bb.4:
- %13:fpr64 = FMOVD0
- B %bb.2
-
- bb.1.for.body.preheader:
- %0:fpr64 = LDRDui %10, 0 :: (load (s64) from %ir.a)
- %1:fpr64 = LDRDui %10, 1 :: (load (s64) from %ir.arrayidx1)
- %16:gpr32 = ORRWrs $wzr, %12, 0
- %2:gpr64all = SUBREG_TO_REG 0, killed %16, %subreg.sub_32
- %15:fpr64 = FMOVD0
- B %bb.3
-
- bb.2.for.cond.cleanup:
- %3:fpr64 = PHI %13, %bb.4, %7, %bb.3
- $d0 = COPY %3
- RET_ReallyLR implicit $d0
-
- bb.3.for.body:
- successors: %bb.2, %bb.3
-
- %4:gpr64sp = PHI %2, %bb.1, %9, %bb.3
- %5:gpr64sp = PHI %11, %bb.1, %8, %bb.3
- %6:fpr64 = PHI %15, %bb.1, %7, %bb.3
- early-clobber %17:gpr64sp, %18:fpr64 = LDRDpost %5, 8 :: (load (s64) from %ir.lsr.iv)
- %19:fpr64 = nofpexcept FMADDDrrr %0, %18, %0, implicit $fpcr
- %20:fpr64 = nofpexcept FMADDDrrr %19, %18, %19, implicit $fpcr
- %21:fpr64 = nofpexcept FMADDDrrr %20, %18, %20, implicit $fpcr
- %22:fpr64 = nofpexcept FMADDDrrr %21, %18, %21, implicit $fpcr
- %23:fpr64 = nofpexcept FMADDDrrr %22, %18, %22, implicit $fpcr
- %24:fpr64 = nofpexcept FMADDDrrr %23, %18, %23, implicit $fpcr
- %25:fpr64 = nofpexcept FMADDDrrr %24, %18, %24, implicit $fpcr
- %26:fpr64 = nofpexcept FMADDDrrr %25, %18, %25, implicit $fpcr
- %27:fpr64 = nofpexcept FMADDDrrr %26, %18, %26, implicit $fpcr
- %28:fpr64 = nofpexcept FMADDDrrr %27, %18, %27, implicit $fpcr
- %29:fpr64 = nofpexcept FMADDDrrr %28, %18, %28, implicit $fpcr
- %30:fpr64 = nofpexcept FMADDDrrr %29, %18, %29, implicit $fpcr
- %31:fpr64 = nofpexcept FMADDDrrr %30, %18, %30, implicit $fpcr
- %32:fpr64 = nofpexcept FMADDDrrr %31, %18, %31, implicit $fpcr
- %33:fpr64 = nofpexcept FMADDDrrr %32, %18, %32, implicit $fpcr
- %34:fpr64 = nofpexcept FMADDDrrr %33, %18, %33, implicit $fpcr
- %35:fpr64 = nofpexcept FADDDrr %33, %34, implicit $fpcr
- %36:fpr64 = nofpexcept FMADDDrrr %34, %18, killed %35, implicit $fpcr
- %37:fpr64 = nofpexcept FADDDrr %26, killed %36, implicit $fpcr
- %38:fpr64 = nofpexcept FMADDDrrr %19, %18, killed %37, implicit $fpcr
- %39:fpr64 = nofpexcept FADDDrr %27, killed %38, implicit $fpcr
- %40:fpr64 = nofpexcept FMADDDrrr %20, %18, killed %39, implicit $fpcr
- %41:fpr64 = nofpexcept FADDDrr %28, killed %40, implicit $fpcr
- %42:fpr64 = nofpexcept FMADDDrrr %21, %18, killed %41, implicit $fpcr
- %43:fpr64 = nofpexcept FADDDrr %30, %31, implicit $fpcr
- %44:fpr64 = nofpexcept FADDDrr %29, killed %43, implicit $fpcr
- %45:fpr64 = nofpexcept FADDDrr killed %44, killed %42, implicit $fpcr
- %46:fpr64 = nofpexcept FMADDDrrr %22, %18, killed %45, implicit $fpcr
- %47:fpr64 = nofpexcept FMULDrr %18, %23, implicit $fpcr
- %48:fpr64 = nofpexcept FMULDrr %1, killed %47, implicit $fpcr
- %49:fpr64 = nofpexcept FMADDDrrr killed %48, %25, killed %46, implicit $fpcr
- %50:fpr64 = nofpexcept FMADDDrrr %24, %1, killed %49, implicit $fpcr
- %7:fpr64 = nofpexcept FADDDrr %6, killed %50, implicit $fpcr
- %8:gpr64all = COPY %17
- %51:gpr64 = nsw SUBSXri %4, 1, 0, implicit-def $nzcv
- %9:gpr64all = COPY %51
- Bcc 0, %bb.2, implicit $nzcv
- B %bb.3
-
-...
diff --git a/llvm/test/CodeGen/PowerPC/sms-regpress.mir b/llvm/test/CodeGen/PowerPC/sms-regpress.mir
index b01115c49fd8..cebd78af882d 100644
--- a/llvm/test/CodeGen/PowerPC/sms-regpress.mir
+++ b/llvm/test/CodeGen/PowerPC/sms-regpress.mir
@@ -1,30 +1,41 @@
-# RUN: llc --verify-machineinstrs -mcpu=pwr9 -o - %s -run-pass=pipeliner -ppc-enable-pipeliner -pipeliner-register-pressure -pipeliner-max-mii=50 -pipeliner-ii-search-range=30 -pipeliner-max-stages=10 -debug-only=pipeliner 2>&1 | FileCheck %s
+# RUN: llc --verify-machineinstrs -mcpu=pwr9 -o - %s -run-pass=pipeliner -ppc-enable-pipeliner -pipeliner-register-pressure -pipeliner-max-mii=50 -pipeliner-ii-search-range=30 -pipeliner-max-stages=10 -debug-only=pipeliner 2>&1 | FileCheck %s
# REQUIRES: asserts
# Check that if the register pressure is too high, the schedule is rejected, II is incremented, and scheduling continues.
# The specific value of II is not important.
-# CHECK: {{^ *}}Try to schedule with {{[0-9]+$}}
-# CHECK: {{^ *}}Rejected the schedule because of too high register pressure{{$}}
-# CHECK: {{^ *}}Try to schedule with {{[0-9]+$}}
-# CHECK: {{^ *}}Schedule Found? 1 (II={{[0-9]+}}){{$}}
+# CHECK: Try to schedule with 21
+# CHECK: Can't schedule
+# CHECK: Try to schedule with 22
+# CHECK: Can't schedule
+# CHECK: Try to schedule with 23
+# CHECK: Rejected the schedule because of too high register pressure
+# CHECK: Try to schedule with 24
+# CHECK: Rejected the schedule because of too high register pressure
+# CHECK: Try to schedule with 25
+# CHECK: Rejected the schedule because of too high register pressure
+# CHECK: Try to schedule with 26
+# CHECK: Schedule Found? 1 (II=26)
--- |
+ ; ModuleID = 'a.ll'
+ source_filename = "a.c"
target datalayout = "e-m:e-Fn32-i64:64-n32:64"
target triple = "ppc64le"
- define dso_local double @kernel(ptr nocapture noundef readonly %a, ptr nocapture noundef readonly %b, i32 noundef signext %n) local_unnamed_addr {
+ ; Function Attrs: nofree nosync nounwind memory(argmem: read) uwtable
+ define dso_local double @kernel(ptr nocapture noundef readonly %a, ptr nocapture noundef readonly %b, i32 noundef signext %n) local_unnamed_addr #0 {
entry:
- %0 = load double, ptr %a, align 8
- %arrayidx1 = getelementptr inbounds i8, ptr %a, i64 8
- %1 = load double, ptr %arrayidx1, align 8
+ %0 = load double, ptr %a, align 8, !tbaa !3
+ %arrayidx1 = getelementptr inbounds double, ptr %a, i64 1
+ %1 = load double, ptr %arrayidx1, align 8, !tbaa !3
%cmp163 = icmp sgt i32 %n, 0
br i1 %cmp163, label %for.body.preheader, label %for.cond.cleanup
for.body.preheader: ; preds = %entry
- %wide.trip.count = zext nneg i32 %n to i64
- %scevgep167 = getelementptr i8, ptr %b, i64 -8
+ %wide.trip.count = zext i32 %n to i64
+ %scevgep1 = getelementptr i8, ptr %b, i64 -8
call void @llvm.set.loop.iterations.i64(i64 %wide.trip.count)
br label %for.body
@@ -32,11 +43,11 @@
%res.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %30, %for.body ]
ret double %res.0.lcssa
- for.body: ; preds = %for.body.preheader, %for.body
+ for.body: ; preds = %for.body, %for.body.preheader
%res.0165 = phi double [ 0.000000e+00, %for.body.preheader ], [ %30, %for.body ]
- %2 = phi ptr [ %scevgep167, %for.body.preheader ], [ %3, %for.body ]
+ %2 = phi ptr [ %scevgep1, %for.body.preheader ], [ %3, %for.body ]
%3 = getelementptr i8, ptr %2, i64 8
- %4 = load double, ptr %3, align 8
+ %4 = load double, ptr %3, align 8, !tbaa !3
%5 = tail call double @llvm.fmuladd.f64(double %0, double %4, double %0)
%6 = tail call double @llvm.fmuladd.f64(double %5, double %4, double %5)
%7 = tail call double @llvm.fmuladd.f64(double %6, double %4, double %6)
@@ -81,23 +92,152 @@
%mul66 = fmul double %12, %mul65
%30 = tail call double @llvm.fmuladd.f64(double %mul66, double %10, double %res.0165)
%31 = call i1 @llvm.loop.decrement.i64(i64 1)
- br i1 %31, label %for.body, label %for.cond.cleanup
+ br i1 %31, label %for.body, label %for.cond.cleanup, !llvm.loop !7
}
- declare double @llvm.fmuladd.f64(double, double, double)
+ ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+ declare double @llvm.fmuladd.f64(double, double, double) #1
- declare void @llvm.set.loop.iterations.i64(i64)
+ ; Function Attrs: nocallback noduplicate nofree nosync nounwind willreturn
+ declare void @llvm.set.loop.iterations.i64(i64) #2
- declare i1 @llvm.loop.decrement.i64(i64)
+ ; Function Attrs: nocallback noduplicate nofree nosync nounwind willreturn
+ declare i1 @llvm.loop.decrement.i64(i64) #2
+ attributes #0 = { nofree nosync nounwind memory(argmem: read) uwtable "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr9" "target-features"="+altivec,+bpermd,+crbits,+crypto,+direct-move,+extdiv,+htm,+isa-v206-instructions,+isa-v207-instructions,+isa-v30-instructions,+power8-vector,+power9-vector,+quadword-atomics,+vsx,-aix-small-local-exec-tls,-privileged,-rop-protect,-spe" }
+ attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+ attributes #2 = { nocallback noduplicate nofree nosync nounwind willreturn }
+
+ !llvm.module.flags = !{!0, !1}
+ !llvm.ident = !{!2}
+
+ !0 = !{i32 1, !"wchar_size", i32 4}
+ !1 = !{i32 7, !"uwtable", i32 2}
+ !2 = !{!"clang version 18.0.0 (https://miratech-soft@dev.azure.com/miratech-soft/llvm/_git/llvm c8d01fb665fc5d9378100a6d92ebcd3be49be655)"}
+ !3 = !{!4, !4, i64 0}
+ !4 = !{!"double", !5, i64 0}
+ !5 = !{!"omnipotent char", !6, i64 0}
+ !6 = !{!"Simple C/C++ TBAA"}
+ !7 = distinct !{!7, !8, !9}
+ !8 = !{!"llvm.loop.mustprogress"}
+ !9 = !{!"llvm.loop.unroll.disable"}
+
...
---
name: kernel
+alignment: 16
+exposesReturnsTwice: false
+legalized: false
+regBankSelected: false
+selected: false
+failedISel: false
tracksRegLiveness: true
+hasWinCFI: false
+callsEHReturn: false
+callsUnwindInit: false
+hasEHCatchret: false
+hasEHScopes: false
+hasEHFunclets: false
+isOutlined: false
+debugInstrRef: false
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+ - { id: 0, class: vsfrc, preferred-register: '' }
+ - { id: 1, class: vsfrc, preferred-register: '' }
+ - { id: 2, class: g8rc, preferred-register: '' }
+ - { id: 3, class: vsfrc, preferred-register: '' }
+ - { id: 4, class: vsfrc, preferred-register: '' }
+ - { id: 5, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+ - { id: 6, class: g8rc, preferred-register: '' }
+ - { id: 7, class: vsfrc, preferred-register: '' }
+ - { id: 8, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+ - { id: 9, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+ - { id: 10, class: g8rc, preferred-register: '' }
+ - { id: 11, class: gprc, preferred-register: '' }
+ - { id: 12, class: vsfrc, preferred-register: '' }
+ - { id: 13, class: crrc, preferred-register: '' }
+ - { id: 14, class: vsfrc, preferred-register: '' }
+ - { id: 15, class: g8rc, preferred-register: '' }
+ - { id: 16, class: g8rc, preferred-register: '' }
+ - { id: 17, class: g8rc, preferred-register: '' }
+ - { id: 18, class: f8rc, preferred-register: '' }
+ - { id: 19, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+ - { id: 20, class: vsfrc, preferred-register: '' }
+ - { id: 21, class: vsfrc, preferred-register: '' }
+ - { id: 22, class: vsfrc, preferred-register: '' }
+ - { id: 23, class: vsfrc, preferred-register: '' }
+ - { id: 24, class: vsfrc, preferred-register: '' }
+ - { id: 25, class: vsfrc, preferred-register: '' }
+ - { id: 26, class: vsfrc, preferred-register: '' }
+ - { id: 27, class: vsfrc, preferred-register: '' }
+ - { id: 28, class: vsfrc, preferred-register: '' }
+ - { id: 29, class: vsfrc, preferred-register: '' }
+ - { id: 30, class: vsfrc, preferred-register: '' }
+ - { id: 31, class: vsfrc, preferred-register: '' }
+ - { id: 32, class: vsfrc, preferred-register: '' }
+ - { id: 33, class: vsfrc, preferred-register: '' }
+ - { id: 34, class: vsfrc, preferred-register: '' }
+ - { id: 35, class: vsfrc, preferred-register: '' }
+ - { id: 36, class: vsfrc, preferred-register: '' }
+ - { id: 37, class: vsfrc, preferred-register: '' }
+ - { id: 38, class: vsfrc, preferred-register: '' }
+ - { id: 39, class: vsfrc, preferred-register: '' }
+ - { id: 40, class: vsfrc, preferred-register: '' }
+ - { id: 41, class: vsfrc, preferred-register: '' }
+ - { id: 42, class: vsfrc, preferred-register: '' }
+ - { id: 43, class: vsfrc, preferred-register: '' }
+ - { id: 44, class: vsfrc, preferred-register: '' }
+ - { id: 45, class: vsfrc, preferred-register: '' }
+ - { id: 46, class: vsfrc, preferred-register: '' }
+ - { id: 47, class: vsfrc, preferred-register: '' }
+ - { id: 48, class: vsfrc, preferred-register: '' }
+ - { id: 49, class: vsfrc, preferred-register: '' }
+ - { id: 50, class: vsfrc, preferred-register: '' }
+ - { id: 51, class: vsfrc, preferred-register: '' }
+ - { id: 52, class: vsfrc, preferred-register: '' }
+ - { id: 53, class: vsfrc, preferred-register: '' }
+ - { id: 54, class: vsfrc, preferred-register: '' }
+ - { id: 55, class: vsfrc, preferred-register: '' }
+ - { id: 56, class: vsfrc, preferred-register: '' }
+ - { id: 57, class: vsfrc, preferred-register: '' }
+ - { id: 58, class: vsfrc, preferred-register: '' }
+ - { id: 59, class: vsfrc, preferred-register: '' }
+ - { id: 60, class: vsfrc, preferred-register: '' }
+ - { id: 61, class: vsfrc, preferred-register: '' }
+ - { id: 62, class: crbitrc, preferred-register: '' }
liveins:
- { reg: '$x3', virtual-reg: '%8' }
- { reg: '$x4', virtual-reg: '%9' }
- { reg: '$x5', virtual-reg: '%10' }
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 0
+ offsetAdjustment: 0
+ maxAlignment: 1
+ adjustsStack: false
+ hasCalls: false
+ stackProtector: ''
+ functionContext: ''
+ maxCallFrameSize: 4294967295
+ cvBytesOfCalleeSavedRegisters: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+ hasTailCall: false
+ localFrameSize: 0
+ savePoint: ''
+ restorePoint: ''
+fixedStack: []
+stack: []
+entry_values: []
+callSites: []
+debugValueSubstitutions: []
+constants: []
+machineFunctionInfo: {}
body: |
bb.0.entry:
successors: %bb.2(0x50000000), %bb.1(0x30000000)
@@ -111,12 +251,16 @@ body: |
BCC 44, killed %13, %bb.2
bb.1:
+ successors: %bb.3(0x80000000)
+
%12:vsfrc = XXLXORdpz
B %bb.3
bb.2.for.body.preheader:
- %0:vsfrc = DFLOADf64 0, %8 :: (load (s64) from %ir.a)
- %1:vsfrc = DFLOADf64 8, killed %8 :: (load (s64) from %ir.arrayidx1)
+ successors: %bb.4(0x80000000)
+
+ %0:vsfrc = DFLOADf64 0, %8 :: (load (s64) from %ir.a, !tbaa !3)
+ %1:vsfrc = DFLOADf64 8, killed %8 :: (load (s64) from %ir.arrayidx1, !tbaa !3)
%16:g8rc = IMPLICIT_DEF
%15:g8rc = INSERT_SUBREG killed %16, killed %11, %subreg.sub_32
%17:g8rc = RLDICL killed %15, 0, 32
@@ -135,7 +279,7 @@ body: |
%4:vsfrc = PHI %14, %bb.2, %7, %bb.4
%5:g8rc_and_g8rc_nox0 = PHI %2, %bb.2, %6, %bb.4
- %18:f8rc, %19:g8rc_and_g8rc_nox0 = LFDU 8, killed %5 :: (load (s64) from %ir.3)
+ %18:f8rc, %19:g8rc_and_g8rc_nox0 = LFDU 8, killed %5 :: (load (s64) from %ir.3, !tbaa !3)
%6:g8rc = COPY killed %19
%20:vsfrc = nofpexcept XSMADDADP %0, %0, %18, implicit $rm
%21:vsfrc = nofpexcept XSMADDADP %20, %20, %18, implicit $rm
--
GitLab
From e45f6e569dafd4033f86d276065d77799b5f6226 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov
Date: Mon, 1 Apr 2024 22:37:37 +0400
Subject: [PATCH 005/442] [clang] Factor out OpenACC part of `Sema` (#84184)
This patch moves OpenACC parts of `Sema` into a separate class
`SemaOpenACC` that is placed in a separate header `Sema/SemaOpenACC.h`.
This patch is intended to be a model of factoring things out of `Sema`,
so I picked a small OpenACC part.
Goals are the following:
1) Split `Sema` into manageable parts.
2) Make dependencies between parts visible.
3) Improve Clang development cycle by avoiding recompiling unrelated
parts of the compiler.
4) Avoid compile-time regressions.
5) Avoid notational regressions in the code that uses Sema.
---
clang/include/clang/Sema/Sema.h | 65 ++++------------------
clang/include/clang/Sema/SemaOpenACC.h | 74 ++++++++++++++++++++++++++
clang/lib/Parse/ParseOpenACC.cpp | 21 ++++----
clang/lib/Sema/JumpDiagnostics.cpp | 1 +
clang/lib/Sema/Sema.cpp | 3 +-
clang/lib/Sema/SemaOpenACC.cpp | 33 +++++++-----
clang/lib/Sema/TreeTransform.h | 11 ++--
7 files changed, 125 insertions(+), 83 deletions(-)
create mode 100644 clang/include/clang/Sema/SemaOpenACC.h
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 3a1abd4c7892..a02b684f2c77 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -33,7 +33,6 @@
#include "clang/AST/NSAPI.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtOpenACC.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeOrdering.h"
@@ -42,7 +41,6 @@
#include "clang/Basic/DarwinSDKInfo.h"
#include "clang/Basic/ExpressionTraits.h"
#include "clang/Basic/Module.h"
-#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/OpenCLOptions.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/PragmaKinds.h"
@@ -183,6 +181,7 @@ class Preprocessor;
class PseudoDestructorTypeStorage;
class PseudoObjectExpr;
class QualType;
+class SemaOpenACC;
class StandardConversionSequence;
class Stmt;
class StringLiteral;
@@ -466,9 +465,8 @@ class Sema final {
// 37. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp)
// 38. CUDA (SemaCUDA.cpp)
// 39. HLSL Constructs (SemaHLSL.cpp)
- // 40. OpenACC Constructs (SemaOpenACC.cpp)
- // 41. OpenMP Directives and Clauses (SemaOpenMP.cpp)
- // 42. SYCL Constructs (SemaSYCL.cpp)
+ // 40. OpenMP Directives and Clauses (SemaOpenMP.cpp)
+ // 41. SYCL Constructs (SemaSYCL.cpp)
/// \name Semantic Analysis
/// Implementations are in Sema.cpp
@@ -1162,6 +1160,11 @@ public:
/// CurContext - This is the current declaration context of parsing.
DeclContext *CurContext;
+ SemaOpenACC &OpenACC() {
+ assert(OpenACCPtr);
+ return *OpenACCPtr;
+ }
+
protected:
friend class Parser;
friend class InitializationSequence;
@@ -1192,6 +1195,8 @@ private:
mutable IdentifierInfo *Ident_super;
+ std::unique_ptr OpenACCPtr;
+
///@}
//
@@ -13351,56 +13356,6 @@ public:
//
//
- /// \name OpenACC Constructs
- /// Implementations are in SemaOpenACC.cpp
- ///@{
-
-public:
- /// Called after parsing an OpenACC Clause so that it can be checked.
- bool ActOnOpenACCClause(OpenACCClauseKind ClauseKind,
- SourceLocation StartLoc);
-
- /// Called after the construct has been parsed, but clauses haven't been
- /// parsed. This allows us to diagnose not-implemented, as well as set up any
- /// state required for parsing the clauses.
- void ActOnOpenACCConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc);
-
- /// Called after the directive, including its clauses, have been parsed and
- /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
- /// happen before any associated declarations or statements have been parsed.
- /// This function is only called when we are parsing a 'statement' context.
- bool ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K,
- SourceLocation StartLoc);
-
- /// Called after the directive, including its clauses, have been parsed and
- /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
- /// happen before any associated declarations or statements have been parsed.
- /// This function is only called when we are parsing a 'Decl' context.
- bool ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K,
- SourceLocation StartLoc);
- /// Called when we encounter an associated statement for our construct, this
- /// should check legality of the statement as it appertains to this Construct.
- StmtResult ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
- StmtResult AssocStmt);
-
- /// Called after the directive has been completely parsed, including the
- /// declaration group or associated statement.
- StmtResult ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- StmtResult AssocStmt);
- /// Called after the directive has been completely parsed, including the
- /// declaration group or associated statement.
- DeclGroupRef ActOnEndOpenACCDeclDirective();
-
- ///@}
-
- //
- //
- // -------------------------------------------------------------------------
- //
- //
-
/// \name OpenMP Directives and Clauses
/// Implementations are in SemaOpenMP.cpp
///@{
diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
new file mode 100644
index 000000000000..7f50d7889ad7
--- /dev/null
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -0,0 +1,74 @@
+//===----- SemaOpenACC.h - Semantic Analysis for OpenACC constructs -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file declares semantic analysis for OpenACC constructs and
+/// clauses.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_SEMAOPENACC_H
+#define LLVM_CLANG_SEMA_SEMAOPENACC_H
+
+#include "clang/AST/DeclGroup.h"
+#include "clang/Basic/OpenACCKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Sema/Ownership.h"
+
+namespace clang {
+
+class ASTContext;
+class DiagnosticEngine;
+class LangOptions;
+class Sema;
+
+class SemaOpenACC {
+public:
+ SemaOpenACC(Sema &S);
+
+ ASTContext &getASTContext() const;
+ DiagnosticsEngine &getDiagnostics() const;
+ const LangOptions &getLangOpts() const;
+
+ Sema &SemaRef;
+
+ /// Called after parsing an OpenACC Clause so that it can be checked.
+ bool ActOnClause(OpenACCClauseKind ClauseKind, SourceLocation StartLoc);
+
+ /// Called after the construct has been parsed, but clauses haven't been
+ /// parsed. This allows us to diagnose not-implemented, as well as set up any
+ /// state required for parsing the clauses.
+ void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc);
+
+ /// Called after the directive, including its clauses, have been parsed and
+ /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
+ /// happen before any associated declarations or statements have been parsed.
+ /// This function is only called when we are parsing a 'statement' context.
+ bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc);
+
+ /// Called after the directive, including its clauses, have been parsed and
+ /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
+ /// happen before any associated declarations or statements have been parsed.
+ /// This function is only called when we are parsing a 'Decl' context.
+ bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc);
+ /// Called when we encounter an associated statement for our construct, this
+ /// should check legality of the statement as it appertains to this Construct.
+ StmtResult ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt);
+
+ /// Called after the directive has been completely parsed, including the
+ /// declaration group or associated statement.
+ StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc, StmtResult AssocStmt);
+ /// Called after the directive has been completely parsed, including the
+ /// declaration group or associated statement.
+ DeclGroupRef ActOnEndDeclDirective();
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_SEMA_SEMAOPENACC_H
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 50e3c39f6091..07dd2ba0106a 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -14,6 +14,7 @@
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
+#include "clang/Sema/SemaOpenACC.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
@@ -777,7 +778,7 @@ bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) {
SourceLocation ClauseLoc = ConsumeToken();
bool Result = ParseOpenACCClauseParams(DirKind, Kind);
- getActions().ActOnOpenACCClause(Kind, ClauseLoc);
+ getActions().OpenACC().ActOnClause(Kind, ClauseLoc);
return Result;
}
@@ -1151,7 +1152,7 @@ Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() {
SourceLocation StartLoc = getCurToken().getLocation();
OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this);
- getActions().ActOnOpenACCConstruct(DirKind, StartLoc);
+ getActions().OpenACC().ActOnConstruct(DirKind, StartLoc);
// Once we've parsed the construct/directive name, some have additional
// specifiers that need to be taken care of. Atomic has an 'atomic-clause'
@@ -1223,12 +1224,12 @@ Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() {
OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
- if (getActions().ActOnStartOpenACCDeclDirective(DirInfo.DirKind,
- DirInfo.StartLoc))
+ if (getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind,
+ DirInfo.StartLoc))
return nullptr;
// TODO OpenACC: Do whatever decl parsing is required here.
- return DeclGroupPtrTy::make(getActions().ActOnEndOpenACCDeclDirective());
+ return DeclGroupPtrTy::make(getActions().OpenACC().ActOnEndDeclDirective());
}
// Parse OpenACC Directive on a Statement.
@@ -1239,8 +1240,8 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() {
ConsumeAnnotationToken();
OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
- if (getActions().ActOnStartOpenACCStmtDirective(DirInfo.DirKind,
- DirInfo.StartLoc))
+ if (getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind,
+ DirInfo.StartLoc))
return StmtError();
StmtResult AssocStmt;
@@ -1249,10 +1250,10 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() {
ParsingOpenACCDirectiveRAII DirScope(*this, /*Value=*/false);
ParseScope ACCScope(this, getOpenACCScopeFlags(DirInfo.DirKind));
- AssocStmt = getActions().ActOnOpenACCAssociatedStmt(DirInfo.DirKind,
- ParseStatement());
+ AssocStmt = getActions().OpenACC().ActOnAssociatedStmt(DirInfo.DirKind,
+ ParseStatement());
}
- return getActions().ActOnEndOpenACCStmtDirective(
+ return getActions().OpenACC().ActOnEndStmtDirective(
DirInfo.DirKind, DirInfo.StartLoc, DirInfo.EndLoc, AssocStmt);
}
diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp
index 6722878883be..ce6211c23218 100644
--- a/clang/lib/Sema/JumpDiagnostics.cpp
+++ b/clang/lib/Sema/JumpDiagnostics.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtOpenACC.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaInternal.h"
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index c9dbac0dfc33..b7e4fc0ac9b5 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -43,6 +43,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/SemaOpenACC.h"
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Sema/TemplateInstCallback.h"
#include "clang/Sema/TypoCorrection.h"
@@ -196,7 +197,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
ThreadSafetyDeclCache(nullptr), LateTemplateParser(nullptr),
LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr),
CurContext(nullptr), ExternalSource(nullptr), CurScope(nullptr),
- Ident_super(nullptr),
+ Ident_super(nullptr), OpenACCPtr(std::make_unique(*this)),
MSPointerToMemberRepresentationMethod(
LangOpts.getMSPointerToMemberRepresentationMethod()),
MSStructPragmaOn(false), VtorDispStack(LangOpts.getVtorDispMode()),
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index d3a602d1c382..2ac994cac71e 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -11,14 +11,15 @@
///
//===----------------------------------------------------------------------===//
+#include "clang/AST/StmtOpenACC.h"
+#include "clang/Sema/SemaOpenACC.h"
#include "clang/Basic/DiagnosticSema.h"
-#include "clang/Basic/OpenACCKinds.h"
#include "clang/Sema/Sema.h"
using namespace clang;
namespace {
-bool diagnoseConstructAppertainment(Sema &S, OpenACCDirectiveKind K,
+bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K,
SourceLocation StartLoc, bool IsStmt) {
switch (K) {
default:
@@ -30,14 +31,21 @@ bool diagnoseConstructAppertainment(Sema &S, OpenACCDirectiveKind K,
case OpenACCDirectiveKind::Serial:
case OpenACCDirectiveKind::Kernels:
if (!IsStmt)
- return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
+ return S.SemaRef.Diag(StartLoc, diag::err_acc_construct_appertainment)
+ << K;
break;
}
return false;
}
} // namespace
-bool Sema::ActOnOpenACCClause(OpenACCClauseKind ClauseKind,
+SemaOpenACC::SemaOpenACC(Sema &S) : SemaRef(S) {}
+
+ASTContext &SemaOpenACC::getASTContext() const { return SemaRef.Context; }
+DiagnosticsEngine &SemaOpenACC::getDiagnostics() const { return SemaRef.Diags; }
+const LangOptions &SemaOpenACC::getLangOpts() const { return SemaRef.LangOpts; }
+
+bool SemaOpenACC::ActOnClause(OpenACCClauseKind ClauseKind,
SourceLocation StartLoc) {
if (ClauseKind == OpenACCClauseKind::Invalid)
return false;
@@ -45,9 +53,10 @@ bool Sema::ActOnOpenACCClause(OpenACCClauseKind ClauseKind,
// whatever it can do. This function will eventually need to start returning
// some sort of Clause AST type, but for now just return true/false based on
// success.
- return Diag(StartLoc, diag::warn_acc_clause_unimplemented) << ClauseKind;
+ return SemaRef.Diag(StartLoc, diag::warn_acc_clause_unimplemented)
+ << ClauseKind;
}
-void Sema::ActOnOpenACCConstruct(OpenACCDirectiveKind K,
+void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
SourceLocation StartLoc) {
switch (K) {
case OpenACCDirectiveKind::Invalid:
@@ -63,17 +72,17 @@ void Sema::ActOnOpenACCConstruct(OpenACCDirectiveKind K,
// here as these constructs do not take any arguments.
break;
default:
- Diag(StartLoc, diag::warn_acc_construct_unimplemented) << K;
+ SemaRef.Diag(StartLoc, diag::warn_acc_construct_unimplemented) << K;
break;
}
}
-bool Sema::ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K,
+bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc) {
return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
}
-StmtResult Sema::ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
+StmtResult SemaOpenACC::ActOnEndStmtDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc,
SourceLocation EndLoc,
StmtResult AssocStmt) {
@@ -92,7 +101,7 @@ StmtResult Sema::ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
llvm_unreachable("Unhandled case in directive handling?");
}
-StmtResult Sema::ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
+StmtResult SemaOpenACC::ActOnAssociatedStmt(OpenACCDirectiveKind K,
StmtResult AssocStmt) {
switch (K) {
default:
@@ -114,9 +123,9 @@ StmtResult Sema::ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
llvm_unreachable("Invalid associated statement application");
}
-bool Sema::ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K,
+bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc) {
return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
}
-DeclGroupRef Sema::ActOnEndOpenACCDeclDirective() { return DeclGroupRef{}; }
+DeclGroupRef SemaOpenACC::ActOnEndDeclDirective() { return DeclGroupRef{}; }
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index eace1bfdff5a..a2568ad0f82c 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -39,6 +39,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/SemaOpenACC.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ErrorHandling.h"
#include
@@ -4000,16 +4001,16 @@ public:
SourceLocation BeginLoc,
SourceLocation EndLoc,
StmtResult StrBlock) {
- getSema().ActOnOpenACCConstruct(K, BeginLoc);
+ getSema().OpenACC().ActOnConstruct(K, BeginLoc);
// TODO OpenACC: Include clauses.
- if (getSema().ActOnStartOpenACCStmtDirective(K, BeginLoc))
+ if (getSema().OpenACC().ActOnStartStmtDirective(K, BeginLoc))
return StmtError();
- StrBlock = getSema().ActOnOpenACCAssociatedStmt(K, StrBlock);
+ StrBlock = getSema().OpenACC().ActOnAssociatedStmt(K, StrBlock);
- return getSema().ActOnEndOpenACCStmtDirective(K, BeginLoc, EndLoc,
- StrBlock);
+ return getSema().OpenACC().ActOnEndStmtDirective(K, BeginLoc, EndLoc,
+ StrBlock);
}
private:
--
GitLab
From f3ec73fca492124b15c3eb9a3ae12b7d86470d27 Mon Sep 17 00:00:00 2001
From: Mingming Liu
Date: Mon, 1 Apr 2024 11:47:11 -0700
Subject: [PATCH 006/442] [NFC]Precommit test for vtable import (#79363)
A precommit test case to show function summary and global values when a function has instructions annotated with vtable profiles and indirect call profiles.
- This is a precommit test for https://github.com/llvm/llvm-project/pull/79381
---
.../thinlto-func-summary-vtableref-pgo.ll | 61 +++++++++++++++++++
1 file changed, 61 insertions(+)
create mode 100644 llvm/test/Bitcode/thinlto-func-summary-vtableref-pgo.ll
diff --git a/llvm/test/Bitcode/thinlto-func-summary-vtableref-pgo.ll b/llvm/test/Bitcode/thinlto-func-summary-vtableref-pgo.ll
new file mode 100644
index 000000000000..78b175caca85
--- /dev/null
+++ b/llvm/test/Bitcode/thinlto-func-summary-vtableref-pgo.ll
@@ -0,0 +1,61 @@
+; RUN: opt -module-summary %s -o %t.o
+
+; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
+
+; RUN: llvm-dis -o - %t.o | FileCheck %s --check-prefix=DIS
+
+
+; CHECK:
+; CHECK-NEXT:
+; The `VALUE_GUID` below represents the "_ZN4Base4funcEv" referenced by the
+; indirect call instruction.
+; CHECK-NEXT:
+; has the format [valueid, flags, instcount, funcflags,
+; numrefs, rorefcnt, worefcnt,
+; n x (valueid, hotness+tailcall)]
+; CHECK-NEXT:
+; CHECK-NEXT:
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function has one BB and an entry count of 150, so the BB is hot according to
+; ProfileSummary and reflected so in the bitcode (see llvm-dis output).
+define i32 @_Z4testP4Base(ptr %0) !prof !15 {
+ %2 = load ptr, ptr %0, !prof !16
+ %3 = load ptr, ptr %2
+ %4 = tail call i32 %3(ptr %0), !prof !17
+ ret i32 %4
+}
+
+!llvm.module.flags = !{!1}
+
+
+!1 = !{i32 1, !"ProfileSummary", !2}
+!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
+!3 = !{!"ProfileFormat", !"InstrProf"}
+!4 = !{!"TotalCount", i64 10000}
+!5 = !{!"MaxCount", i64 200}
+!6 = !{!"MaxInternalCount", i64 200}
+!7 = !{!"MaxFunctionCount", i64 200}
+!8 = !{!"NumCounts", i64 3}
+!9 = !{!"NumFunctions", i64 3}
+!10 = !{!"DetailedSummary", !11}
+!11 = !{!12, !13, !14}
+!12 = !{i32 10000, i64 100, i32 1}
+!13 = !{i32 990000, i64 100, i32 1}
+!14 = !{i32 999999, i64 1, i32 2}
+
+!15 = !{!"function_entry_count", i32 150}
+; 1960855528937986108 is the MD5 hash of _ZTV4Base
+!16 = !{!"VP", i32 2, i64 1600, i64 1960855528937986108, i64 1600}
+; 5459407273543877811 is the MD5 hash of _ZN4Base4funcEv
+!17 = !{!"VP", i32 0, i64 1600, i64 5459407273543877811, i64 1600}
+
+; ModuleSummaryIndex stores map in std::map; so
+; global value summares are printed out in the order that gv's guid increases.
+; DIS: ^0 = module: (path: "{{.*}}", hash: (0, 0, 0, 0, 0))
+; DIS: ^1 = gv: (guid: 5459407273543877811)
+; DIS: ^2 = gv: (name: "_Z4testP4Base", summaries: (function: (module: ^0, flags: (linkage: external, visibility: default, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), insts: 4, funcFlags: (readNone: 0, readOnly: 0, noRecurse: 0, returnDoesNotAlias: 0, noInline: 0, alwaysInline: 0, noUnwind: 0, mayThrow: 0, hasUnknownCall: 1, mustBeUnreachable: 0), calls: ((callee: ^1, hotness: hot))))) ; guid = 15857150948103218965
+; DIS: ^3 = blockcount: 0
--
GitLab
From cbd48b184eca1ca73e6f20575501d94ad30fbd58 Mon Sep 17 00:00:00 2001
From: Aaron Ballman
Date: Mon, 1 Apr 2024 14:49:56 -0400
Subject: [PATCH 007/442] [C99] Claim conformance to "conversion of array to
pointer not limited to lvalues"
We don't have a document number for this, but the change was called out
explicitly in the editor's comments in the C99 foreword.
---
clang/test/C/C99/array-lvalue.c | 38 +++++++++++++++++++++++++++++++++
clang/www/c_status.html | 2 +-
2 files changed, 39 insertions(+), 1 deletion(-)
create mode 100644 clang/test/C/C99/array-lvalue.c
diff --git a/clang/test/C/C99/array-lvalue.c b/clang/test/C/C99/array-lvalue.c
new file mode 100644
index 000000000000..4e963b4f74fc
--- /dev/null
+++ b/clang/test/C/C99/array-lvalue.c
@@ -0,0 +1,38 @@
+/* RUN: %clang_cc1 -verify -pedantic -std=c99 %s
+ RUN: %clang_cc1 -verify=c89 -pedantic -std=c89 %s
+ expected-no-diagnostics
+ */
+
+/* WG14 ???: Yes
+ * Conversion of array to pointer not limited to lvalues
+ *
+ * NB: the original paper number is unknown, this was gleaned from the editor's report
+ * in the C99 foreword. The C99 rationale document did not shed much light on
+ * the situation either, mostly talking about user confusion between lvalue and
+ * modifiable lvalue. However, the crux of the change was C89 changing:
+ *
+ * C89 3.2.2.1: Except when it is the operand of ..., an lvalue that has type
+ * 'array of type' is converted to an expression that has type 'pointer to
+ * type' that points to the initial element of the array object and is not an
+ * lvalue.
+ *
+ * C99 6.3.2.1p3: Except when it is the operand of ..., an expression that has
+ * type 'array of type' is converted to an expression with type 'pointer to
+ * type' that points to the initial element of the array object and is not an
+ * lvalue.
+ */
+
+struct S {
+ char arr[100];
+};
+
+struct S f(void);
+
+void func(void) {
+ char c;
+ /* The return from f() is an rvalue, so this code is not valid in C89, but is
+ * valid in C99.
+ */
+ c = f().arr[10]; /* c89-warning {{ISO C90 does not allow subscripting non-lvalue array}} */
+}
+
diff --git a/clang/www/c_status.html b/clang/www/c_status.html
index 123897593e5d..803dce8e29fc 100644
--- a/clang/www/c_status.html
+++ b/clang/www/c_status.html
@@ -360,7 +360,7 @@ conformance.
| conversion of array to pointer not limited to lvalues |
Unknown |
- Unknown |
+ Yes |
| relaxed constraints on aggregate and union initialization |
--
GitLab
From 4cd7bb07c7540bf83a7a60a67aa282e99461ca2f Mon Sep 17 00:00:00 2001
From: Kirill Podoprigora
Date: Mon, 1 Apr 2024 22:07:10 +0300
Subject: [PATCH 008/442] [mlir] Remove ``dataclasses`` package from mlir
``requirements.txt`` (#87223)
The ``dataclasses`` package makes sense for Python 3.6, becauses
``dataclasses`` is only included in the standard library with 3.7
version. Now, 3.6 has reached EOL, so all current supported versions of
Python (3.8, 3.9, 3.10, 3.11, 3.12) have this feature in their standard
libraries.
Therefore there's no need to install the ``dataclasses`` package now.
---
mlir/python/requirements.txt | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/mlir/python/requirements.txt b/mlir/python/requirements.txt
index a596f8747ebe..acd6dbb25eda 100644
--- a/mlir/python/requirements.txt
+++ b/mlir/python/requirements.txt
@@ -1,4 +1,3 @@
numpy>=1.19.5, <=1.26
pybind11>=2.9.0, <=2.10.3
-PyYAML>=5.3.1, <=6.0.1
-dataclasses>=0.6, <=0.8
\ No newline at end of file
+PyYAML>=5.3.1, <=6.0.1
\ No newline at end of file
--
GitLab
From ee99475068523de185dce0a449b65e684a1e6b73 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell
Date: Mon, 1 Apr 2024 15:41:38 -0400
Subject: [PATCH 009/442] [clang] Fix bitfield access unit for vbase corner
case (#87238)
This fixes #87227, a vbase can be placed below nvsize when empty members and/or bases are in play. We must account for that.
---
clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 57 +++++++---
.../test/CodeGenCXX/bitfield-access-tail.cpp | 104 ++++++++++++------
2 files changed, 113 insertions(+), 48 deletions(-)
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index e32023aeac1e..634a55fec518 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -185,9 +185,10 @@ struct CGRecordLowering {
/// Lowers an ASTRecordLayout to a llvm type.
void lower(bool NonVirtualBaseType);
void lowerUnion(bool isNoUniqueAddress);
- void accumulateFields();
+ void accumulateFields(bool isNonVirtualBaseType);
RecordDecl::field_iterator
- accumulateBitFields(RecordDecl::field_iterator Field,
+ accumulateBitFields(bool isNonVirtualBaseType,
+ RecordDecl::field_iterator Field,
RecordDecl::field_iterator FieldEnd);
void computeVolatileBitfields();
void accumulateBases();
@@ -195,8 +196,10 @@ struct CGRecordLowering {
void accumulateVBases();
/// Recursively searches all of the bases to find out if a vbase is
/// not the primary vbase of some base class.
- bool hasOwnStorage(const CXXRecordDecl *Decl, const CXXRecordDecl *Query);
+ bool hasOwnStorage(const CXXRecordDecl *Decl,
+ const CXXRecordDecl *Query) const;
void calculateZeroInit();
+ CharUnits calculateTailClippingOffset(bool isNonVirtualBaseType) const;
/// Lowers bitfield storage types to I8 arrays for bitfields with tail
/// padding that is or can potentially be used.
void clipTailPadding();
@@ -287,7 +290,7 @@ void CGRecordLowering::lower(bool NVBaseType) {
computeVolatileBitfields();
return;
}
- accumulateFields();
+ accumulateFields(NVBaseType);
// RD implies C++.
if (RD) {
accumulateVPtrs();
@@ -378,12 +381,12 @@ void CGRecordLowering::lowerUnion(bool isNoUniqueAddress) {
Packed = true;
}
-void CGRecordLowering::accumulateFields() {
+void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) {
for (RecordDecl::field_iterator Field = D->field_begin(),
FieldEnd = D->field_end();
Field != FieldEnd;) {
if (Field->isBitField()) {
- Field = accumulateBitFields(Field, FieldEnd);
+ Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd);
assert((Field == FieldEnd || !Field->isBitField()) &&
"Failed to accumulate all the bitfields");
} else if (Field->isZeroSize(Context)) {
@@ -404,9 +407,12 @@ void CGRecordLowering::accumulateFields() {
}
// Create members for bitfields. Field is a bitfield, and FieldEnd is the end
-// iterator of the record. Return the first non-bitfield encountered.
+// iterator of the record. Return the first non-bitfield encountered. We need
+// to know whether this is the base or complete layout, as virtual bases could
+// affect the upper bound of bitfield access unit allocation.
RecordDecl::field_iterator
-CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
+CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
+ RecordDecl::field_iterator Field,
RecordDecl::field_iterator FieldEnd) {
if (isDiscreteBitFieldABI()) {
// Run stores the first element of the current run of bitfields. FieldEnd is
@@ -505,6 +511,10 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
bitsToCharUnits(Context.getTargetInfo().getRegisterWidth());
unsigned CharBits = Context.getCharWidth();
+ // Limit of useable tail padding at end of the record. Computed lazily and
+ // cached here.
+ CharUnits ScissorOffset = CharUnits::Zero();
+
// Data about the start of the span we're accumulating to create an access
// unit from. Begin is the first bitfield of the span. If Begin is FieldEnd,
// we've not got a current span. The span starts at the BeginOffset character
@@ -630,10 +640,14 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
LimitOffset = bitsToCharUnits(getFieldBitOffset(*Probe));
goto FoundLimit;
}
- // We reached the end of the fields. We can't necessarily use tail
- // padding in C++ structs, so the NonVirtual size is what we must
- // use there.
- LimitOffset = RD ? Layout.getNonVirtualSize() : Layout.getDataSize();
+ // We reached the end of the fields, determine the bounds of useable
+ // tail padding. As this can be complex for C++, we cache the result.
+ if (ScissorOffset.isZero()) {
+ ScissorOffset = calculateTailClippingOffset(isNonVirtualBaseType);
+ assert(!ScissorOffset.isZero() && "Tail clipping at zero");
+ }
+
+ LimitOffset = ScissorOffset;
FoundLimit:;
CharUnits TypeSize = getSize(Type);
@@ -838,13 +852,17 @@ void CGRecordLowering::accumulateVPtrs() {
llvm::PointerType::getUnqual(Types.getLLVMContext())));
}
-void CGRecordLowering::accumulateVBases() {
+CharUnits
+CGRecordLowering::calculateTailClippingOffset(bool isNonVirtualBaseType) const {
+ if (!RD)
+ return Layout.getDataSize();
+
CharUnits ScissorOffset = Layout.getNonVirtualSize();
// In the itanium ABI, it's possible to place a vbase at a dsize that is
// smaller than the nvsize. Here we check to see if such a base is placed
// before the nvsize and set the scissor offset to that, instead of the
// nvsize.
- if (isOverlappingVBaseABI())
+ if (!isNonVirtualBaseType && isOverlappingVBaseABI())
for (const auto &Base : RD->vbases()) {
const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
if (BaseDecl->isEmpty())
@@ -856,8 +874,13 @@ void CGRecordLowering::accumulateVBases() {
ScissorOffset = std::min(ScissorOffset,
Layout.getVBaseClassOffset(BaseDecl));
}
- Members.push_back(MemberInfo(ScissorOffset, MemberInfo::Scissor, nullptr,
- RD));
+
+ return ScissorOffset;
+}
+
+void CGRecordLowering::accumulateVBases() {
+ Members.push_back(MemberInfo(calculateTailClippingOffset(false),
+ MemberInfo::Scissor, nullptr, RD));
for (const auto &Base : RD->vbases()) {
const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
if (BaseDecl->isEmpty())
@@ -882,7 +905,7 @@ void CGRecordLowering::accumulateVBases() {
}
bool CGRecordLowering::hasOwnStorage(const CXXRecordDecl *Decl,
- const CXXRecordDecl *Query) {
+ const CXXRecordDecl *Query) const {
const ASTRecordLayout &DeclLayout = Context.getASTRecordLayout(Decl);
if (DeclLayout.isPrimaryBaseVirtual() && DeclLayout.getPrimaryBase() == Query)
return false;
diff --git a/clang/test/CodeGenCXX/bitfield-access-tail.cpp b/clang/test/CodeGenCXX/bitfield-access-tail.cpp
index 68716fdf3b1d..1539e17cad43 100644
--- a/clang/test/CodeGenCXX/bitfield-access-tail.cpp
+++ b/clang/test/CodeGenCXX/bitfield-access-tail.cpp
@@ -2,45 +2,45 @@
// Configs that have cheap unaligned access
// Little Endian
-// RUN: %clang_cc1 -triple=aarch64-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=aarch64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
+// RUN: %clang_cc1 -triple=aarch64-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=aarch64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
// RUN: %clang_cc1 -triple=arm-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT-DWN32 %s
-// RUN: %clang_cc1 -triple=arm-none-eabi %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=i686-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=loongarch64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=powerpcle-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=ve-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=wasm32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=wasm64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=x86_64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
+// RUN: %clang_cc1 -triple=arm-none-eabi %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=i686-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=loongarch64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=powerpcle-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=ve-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=wasm32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=wasm64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
// Big Endian
-// RUN: %clang_cc1 -triple=powerpc-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=powerpc64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=systemz %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
+// RUN: %clang_cc1 -triple=powerpc-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=powerpc64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=systemz %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
// Configs that have expensive unaligned access
// Little Endian
-// RUN: %clang_cc1 -triple=amdgcn-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=arc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=bpf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=csky %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=hexagon-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=le64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=loongarch32-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=nvptx-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=riscv32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=riscv64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=spir-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=xcore-none-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
+// RUN: %clang_cc1 -triple=amdgcn-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=arc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=bpf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=csky %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=hexagon-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=le64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=loongarch32-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=nvptx-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=riscv32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=riscv64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=spir-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=xcore-none-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
// Big endian
-// RUN: %clang_cc1 -triple=lanai-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=m68k-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=mips-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=mips64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=sparc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
-// RUN: %clang_cc1 -triple=tce-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s
+// RUN: %clang_cc1 -triple=lanai-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=m68k-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=mips-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=mips64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
+// RUN: %clang_cc1 -triple=sparc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
+// RUN: %clang_cc1 -triple=tce-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
// Can use tail padding
struct Pod {
@@ -113,3 +113,45 @@ struct __attribute__((packed)) PNonPod {
// LAYOUT-DWN32-NEXT:
+
+struct __attribute__((aligned(4))) Empty {} empty;
+
+struct Char { char a; } cbase;
+struct D : virtual Char {
+ [[no_unique_address]] Empty e0;
+ [[no_unique_address]] Empty e1;
+ unsigned a : 24; // keep as 24bits
+} d;
+// CHECK-LABEL: LLVMType:%struct.D =
+// LAYOUT64-SAME: type <{ ptr, [3 x i8], %struct.Char, [4 x i8] }>
+// LAYOUT32-SAME: type { ptr, [3 x i8], %struct.Char }
+// LAYOUT-DWN32-SAME: type { ptr, [3 x i8], %struct.Char }
+// CHECK-NEXT: NonVirtualBaseLLVMType:
+// LAYOUT64-SAME: %struct.D.base = type <{ ptr, i32 }>
+// LAYOUT32-SAME: %struct.D = type { ptr, [3 x i8], %struct.Char }
+// LAYOUT-DWN32-SAME: %struct.D = type { ptr, [3 x i8], %struct.Char }
+// CHECK: BitFields:[
+// LAYOUT-NEXT:
+
+struct Int { int a; } ibase;
+struct E : virtual Int {
+ [[no_unique_address]] Empty e0;
+ [[no_unique_address]] Empty e1;
+ unsigned a : 24; // expand to 32
+} e;
+// CHECK-LABEL: LLVMType:%struct.E =
+// LAYOUT64-SAME: type <{ ptr, i32, %struct.Int }>
+// LAYOUT32-SAME: type { ptr, i32, %struct.Int }
+// LAYOUT-DWN32-SAME: type { ptr, i32, %struct.Int }
+// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.E.base =
+// LAYOUT64-SAME: type <{ ptr, i32 }>
+// LAYOUT32-SAME: type { ptr, i32 }
+// LAYOUT-DWN32-SAME: type { ptr, i32 }
+// CHECK: BitFields:[
+// LAYOUT-NEXT:
--
GitLab
From ed6edf262d9061ce3c024754c4981299b5184ee2 Mon Sep 17 00:00:00 2001
From: Christopher Ferris
Date: Mon, 1 Apr 2024 13:35:29 -0700
Subject: [PATCH 010/442] [scudo] Change isPowerOfTwo macro to return false for
zero. (#87120)
Clean-up all of the calls and remove the redundant == 0 checks.
There is only one small visible change. For non-Android, the memalign
function will now fail if alignment is zero. Before this would have
passed.
---
compiler-rt/lib/scudo/standalone/common.h | 6 +++++-
compiler-rt/lib/scudo/standalone/stack_depot.h | 4 ++--
compiler-rt/lib/scudo/standalone/wrappers_c_checks.h | 6 ++----
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/compiler-rt/lib/scudo/standalone/common.h b/compiler-rt/lib/scudo/standalone/common.h
index ae45683f1ee3..151fbd317e74 100644
--- a/compiler-rt/lib/scudo/standalone/common.h
+++ b/compiler-rt/lib/scudo/standalone/common.h
@@ -28,7 +28,11 @@ template inline Dest bit_cast(const Source &S) {
return D;
}
-inline constexpr bool isPowerOfTwo(uptr X) { return (X & (X - 1)) == 0; }
+inline constexpr bool isPowerOfTwo(uptr X) {
+ if (X == 0)
+ return false;
+ return (X & (X - 1)) == 0;
+}
inline constexpr uptr roundUp(uptr X, uptr Boundary) {
DCHECK(isPowerOfTwo(Boundary));
diff --git a/compiler-rt/lib/scudo/standalone/stack_depot.h b/compiler-rt/lib/scudo/standalone/stack_depot.h
index 98cd9707a646..0176c40aa899 100644
--- a/compiler-rt/lib/scudo/standalone/stack_depot.h
+++ b/compiler-rt/lib/scudo/standalone/stack_depot.h
@@ -103,7 +103,7 @@ public:
// Ensure that RingSize, RingMask and TabMask are set up in a way that
// all accesses are within range of BufSize.
bool isValid(uptr BufSize) const {
- if (RingSize == 0 || !isPowerOfTwo(RingSize))
+ if (!isPowerOfTwo(RingSize))
return false;
uptr RingBytes = sizeof(atomic_u64) * RingSize;
if (RingMask + 1 != RingSize)
@@ -112,7 +112,7 @@ public:
if (TabMask == 0)
return false;
uptr TabSize = TabMask + 1;
- if (TabSize == 0 || !isPowerOfTwo(TabSize))
+ if (!isPowerOfTwo(TabSize))
return false;
uptr TabBytes = sizeof(atomic_u32) * TabSize;
diff --git a/compiler-rt/lib/scudo/standalone/wrappers_c_checks.h b/compiler-rt/lib/scudo/standalone/wrappers_c_checks.h
index 9cd48e82792e..d0288699cf1b 100644
--- a/compiler-rt/lib/scudo/standalone/wrappers_c_checks.h
+++ b/compiler-rt/lib/scudo/standalone/wrappers_c_checks.h
@@ -31,15 +31,13 @@ inline void *setErrnoOnNull(void *Ptr) {
// Checks aligned_alloc() parameters, verifies that the alignment is a power of
// two and that the size is a multiple of alignment.
inline bool checkAlignedAllocAlignmentAndSize(uptr Alignment, uptr Size) {
- return Alignment == 0 || !isPowerOfTwo(Alignment) ||
- !isAligned(Size, Alignment);
+ return !isPowerOfTwo(Alignment) || !isAligned(Size, Alignment);
}
// Checks posix_memalign() parameters, verifies that alignment is a power of two
// and a multiple of sizeof(void *).
inline bool checkPosixMemalignAlignment(uptr Alignment) {
- return Alignment == 0 || !isPowerOfTwo(Alignment) ||
- !isAligned(Alignment, sizeof(void *));
+ return !isPowerOfTwo(Alignment) || !isAligned(Alignment, sizeof(void *));
}
// Returns true if calloc(Size, N) overflows on Size*N calculation. Use a
--
GitLab
From e93b5f5a4776ffea12d03652559dfdf8d421184c Mon Sep 17 00:00:00 2001
From: Vitaly Buka
Date: Mon, 1 Apr 2024 13:05:34 -0700
Subject: [PATCH 011/442] [ubsan][NFC] Remove recently added `cl::init(false)`
Extracted from #84858
---
clang/lib/CodeGen/BackendUtil.cpp | 7 +++----
clang/lib/CodeGen/CGExpr.cpp | 3 +--
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 82b30b8d8156..1220c575d1df 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -101,20 +101,19 @@ namespace llvm {
extern cl::opt PrintPipelinePasses;
cl::opt ClRemoveTraps("clang-remove-traps", cl::Optional,
- cl::desc("Insert remove-traps pass."),
- cl::init(false));
+ cl::desc("Insert remove-traps pass."));
// Experiment to move sanitizers earlier.
static cl::opt ClSanitizeOnOptimizerEarlyEP(
"sanitizer-early-opt-ep", cl::Optional,
- cl::desc("Insert sanitizers on OptimizerEarlyEP."), cl::init(false));
+ cl::desc("Insert sanitizers on OptimizerEarlyEP."));
extern cl::opt ProfileCorrelate;
// Re-link builtin bitcodes after optimization
cl::opt ClRelinkBuiltinBitcodePostop(
"relink-builtin-bitcode-postop", cl::Optional,
- cl::desc("Re-link builtin bitcodes after optimization."), cl::init(false));
+ cl::desc("Re-link builtin bitcodes after optimization."));
} // namespace llvm
namespace {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index e0d5575d57d0..54432353e742 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -56,8 +56,7 @@ using namespace CodeGen;
// Experiment to make sanitizers easier to debug
static llvm::cl::opt ClSanitizeDebugDeoptimization(
"ubsan-unique-traps", llvm::cl::Optional,
- llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check"),
- llvm::cl::init(false));
+ llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check"));
//===--------------------------------------------------------------------===//
// Miscellaneous Helper Methods
--
GitLab
From b8cc3ba409dc850776f37e27613bf74f5a80d66a Mon Sep 17 00:00:00 2001
From: Lei Wang
Date: Mon, 1 Apr 2024 13:54:54 -0700
Subject: [PATCH 012/442] [PseudoProbe] Extend to skip instrumenting probe into
the dests of invoke (#79919)
As before we only skip instrumenting probe of `unwind`(`KnownColdBlock`)
block, this PR extends to skip the both EH flow from `invoke`, i.e. also
skip the `normal` dest. For more contexts: when doing call-to-invoke
conversion, the block is split by the `invoke` and two extra
blocks(`normal` and `unwind`) are added. With this PR, the
instrumentation is the same as the one before the call-to-invoke
conversion.
One significant benefit is this can help mitigate the "unstable IR"
issue(https://discourse.llvm.org/t/ipo-for-linkonce-odr-functions/69404),
the two versions now are on the same probe instrumentation, expected to
be the same checksum.
To achieve the same checksum, some tweaks is needed:
- Now it also skips incrementing the probe ID for the skipped probe.
- The checksum is also computed based on the CFG that skips the EH
edges.
We observed this fixes ~5% mismatched samples.
---
llvm/include/llvm/Analysis/EHUtils.h | 1 -
.../llvm/Transforms/IPO/SampleProfileProbe.h | 13 +-
.../lib/Transforms/IPO/SampleProfileProbe.cpp | 121 ++++++++++++--
.../ThinLTO/X86/pseudo-probe-desc-import.ll | 4 +-
.../SampleProfile/pseudo-probe-eh.ll | 2 +-
.../SampleProfile/pseudo-probe-invoke.ll | 155 ++++++++++++++++++
6 files changed, 276 insertions(+), 20 deletions(-)
create mode 100644 llvm/test/Transforms/SampleProfile/pseudo-probe-invoke.ll
diff --git a/llvm/include/llvm/Analysis/EHUtils.h b/llvm/include/llvm/Analysis/EHUtils.h
index f2ff6cbd2e90..3ad0878bd64f 100644
--- a/llvm/include/llvm/Analysis/EHUtils.h
+++ b/llvm/include/llvm/Analysis/EHUtils.h
@@ -79,7 +79,6 @@ static void computeEHOnlyBlocks(FunctionT &F, DenseSet &EHBlocks) {
}
}
- EHBlocks.clear();
for (auto Entry : Statuses) {
if (Entry.second == EH)
EHBlocks.insert(Entry.first);
diff --git a/llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h b/llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h
index 0f2729a9462d..03aa93ce6bd3 100644
--- a/llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h
+++ b/llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h
@@ -81,8 +81,17 @@ private:
uint64_t getFunctionHash() const { return FunctionHash; }
uint32_t getBlockId(const BasicBlock *BB) const;
uint32_t getCallsiteId(const Instruction *Call) const;
- void computeCFGHash();
- void computeProbeIdForBlocks();
+ void findUnreachableBlocks(DenseSet &BlocksToIgnore);
+ void findInvokeNormalDests(DenseSet &InvokeNormalDests);
+ void computeBlocksToIgnore(DenseSet &BlocksToIgnore,
+ DenseSet &BlocksAndCallsToIgnore);
+ void computeProbeIdForCallsites(
+ const DenseSet &BlocksAndCallsToIgnore);
+ const Instruction *
+ getOriginalTerminator(const BasicBlock *Head,
+ const DenseSet &BlocksToIgnore);
+ void computeCFGHash(const DenseSet &BlocksToIgnore);
+ void computeProbeIdForBlocks(const DenseSet &BlocksToIgnore);
void computeProbeIdForCallsites();
Function *F;
diff --git a/llvm/lib/Transforms/IPO/SampleProfileProbe.cpp b/llvm/lib/Transforms/IPO/SampleProfileProbe.cpp
index 090e5560483e..4d0fa24bd57c 100644
--- a/llvm/lib/Transforms/IPO/SampleProfileProbe.cpp
+++ b/llvm/lib/Transforms/IPO/SampleProfileProbe.cpp
@@ -173,21 +173,114 @@ SampleProfileProber::SampleProfileProber(Function &Func,
BlockProbeIds.clear();
CallProbeIds.clear();
LastProbeId = (uint32_t)PseudoProbeReservedId::Last;
- computeProbeIdForBlocks();
- computeProbeIdForCallsites();
- computeCFGHash();
+
+ DenseSet BlocksToIgnore;
+ DenseSet BlocksAndCallsToIgnore;
+ computeBlocksToIgnore(BlocksToIgnore, BlocksAndCallsToIgnore);
+
+ computeProbeIdForBlocks(BlocksToIgnore);
+ computeProbeIdForCallsites(BlocksAndCallsToIgnore);
+ computeCFGHash(BlocksToIgnore);
+}
+
+// Two purposes to compute the blocks to ignore:
+// 1. Reduce the IR size.
+// 2. Make the instrumentation(checksum) stable. e.g. the frondend may
+// generate unstable IR while optimizing nounwind attribute, some versions are
+// optimized with the call-to-invoke conversion, while other versions do not.
+// This discrepancy in probe ID could cause profile mismatching issues.
+// Note that those ignored blocks are either cold blocks or new split blocks
+// whose original blocks are instrumented, so it shouldn't degrade the profile
+// quality.
+void SampleProfileProber::computeBlocksToIgnore(
+ DenseSet &BlocksToIgnore,
+ DenseSet &BlocksAndCallsToIgnore) {
+ // Ignore the cold EH and unreachable blocks and calls.
+ computeEHOnlyBlocks(*F, BlocksAndCallsToIgnore);
+ findUnreachableBlocks(BlocksAndCallsToIgnore);
+
+ BlocksToIgnore.insert(BlocksAndCallsToIgnore.begin(),
+ BlocksAndCallsToIgnore.end());
+
+ // Handle the call-to-invoke conversion case: make sure that the probe id and
+ // callsite id are consistent before and after the block split. For block
+ // probe, we only keep the head block probe id and ignore the block ids of the
+ // normal dests. For callsite probe, it's different to block probe, there is
+ // no additional callsite in the normal dests, so we don't ignore the
+ // callsites.
+ findInvokeNormalDests(BlocksToIgnore);
+}
+
+// Unreachable blocks and calls are always cold, ignore them.
+void SampleProfileProber::findUnreachableBlocks(
+ DenseSet &BlocksToIgnore) {
+ for (auto &BB : *F) {
+ if (&BB != &F->getEntryBlock() && pred_size(&BB) == 0)
+ BlocksToIgnore.insert(&BB);
+ }
+}
+
+// In call-to-invoke conversion, basic block can be split into multiple blocks,
+// only instrument probe in the head block, ignore the normal dests.
+void SampleProfileProber::findInvokeNormalDests(
+ DenseSet &InvokeNormalDests) {
+ for (auto &BB : *F) {
+ auto *TI = BB.getTerminator();
+ if (auto *II = dyn_cast(TI)) {
+ auto *ND = II->getNormalDest();
+ InvokeNormalDests.insert(ND);
+
+ // The normal dest and the try/catch block are connected by an
+ // unconditional branch.
+ while (pred_size(ND) == 1) {
+ auto *Pred = *pred_begin(ND);
+ if (succ_size(Pred) == 1) {
+ InvokeNormalDests.insert(Pred);
+ ND = Pred;
+ } else
+ break;
+ }
+ }
+ }
+}
+
+// The call-to-invoke conversion splits the original block into a list of block,
+// we need to compute the hash using the original block's successors to keep the
+// CFG Hash consistent. For a given head block, we keep searching the
+// succesor(normal dest or unconditional branch dest) to find the tail block,
+// the tail block's successors are the original block's successors.
+const Instruction *SampleProfileProber::getOriginalTerminator(
+ const BasicBlock *Head, const DenseSet &BlocksToIgnore) {
+ auto *TI = Head->getTerminator();
+ if (auto *II = dyn_cast(TI)) {
+ return getOriginalTerminator(II->getNormalDest(), BlocksToIgnore);
+ } else if (succ_size(Head) == 1 &&
+ BlocksToIgnore.contains(*succ_begin(Head))) {
+ // Go to the unconditional branch dest.
+ return getOriginalTerminator(*succ_begin(Head), BlocksToIgnore);
+ }
+ return TI;
}
// Compute Hash value for the CFG: the lower 32 bits are CRC32 of the index
// value of each BB in the CFG. The higher 32 bits record the number of edges
// preceded by the number of indirect calls.
// This is derived from FuncPGOInstrumentation::computeCFGHash().
-void SampleProfileProber::computeCFGHash() {
+void SampleProfileProber::computeCFGHash(
+ const DenseSet &BlocksToIgnore) {
std::vector Indexes;
JamCRC JC;
for (auto &BB : *F) {
- for (BasicBlock *Succ : successors(&BB)) {
+ if (BlocksToIgnore.contains(&BB))
+ continue;
+
+ auto *TI = getOriginalTerminator(&BB, BlocksToIgnore);
+ for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I) {
+ auto *Succ = TI->getSuccessor(I);
auto Index = getBlockId(Succ);
+ // Ingore ignored-block(zero ID) to avoid unstable checksum.
+ if (Index == 0)
+ continue;
for (int J = 0; J < 4; J++)
Indexes.push_back((uint8_t)(Index >> (J * 8)));
}
@@ -207,23 +300,23 @@ void SampleProfileProber::computeCFGHash() {
<< ", Hash = " << FunctionHash << "\n");
}
-void SampleProfileProber::computeProbeIdForBlocks() {
- DenseSet KnownColdBlocks;
- computeEHOnlyBlocks(*F, KnownColdBlocks);
- // Insert pseudo probe to non-cold blocks only. This will reduce IR size as
- // well as the binary size while retaining the profile quality.
+void SampleProfileProber::computeProbeIdForBlocks(
+ const DenseSet &BlocksToIgnore) {
for (auto &BB : *F) {
- ++LastProbeId;
- if (!KnownColdBlocks.contains(&BB))
- BlockProbeIds[&BB] = LastProbeId;
+ if (BlocksToIgnore.contains(&BB))
+ continue;
+ BlockProbeIds[&BB] = ++LastProbeId;
}
}
-void SampleProfileProber::computeProbeIdForCallsites() {
+void SampleProfileProber::computeProbeIdForCallsites(
+ const DenseSet &BlocksAndCallsToIgnore) {
LLVMContext &Ctx = F->getContext();
Module *M = F->getParent();
for (auto &BB : *F) {
+ if (BlocksAndCallsToIgnore.contains(&BB))
+ continue;
for (auto &I : BB) {
if (!isa(I))
continue;
diff --git a/llvm/test/ThinLTO/X86/pseudo-probe-desc-import.ll b/llvm/test/ThinLTO/X86/pseudo-probe-desc-import.ll
index 21dd8c0fe924..f915aaccc06e 100644
--- a/llvm/test/ThinLTO/X86/pseudo-probe-desc-import.ll
+++ b/llvm/test/ThinLTO/X86/pseudo-probe-desc-import.ll
@@ -12,8 +12,8 @@
; RUN: llvm-lto -thinlto-action=import %t3.bc -thinlto-index=%t3.index.bc -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
-; CHECK-NOT: {i64 6699318081062747564, i64 4294967295, !"foo"
-; CHECK: !{i64 -2624081020897602054, i64 281479271677951, !"main"
+; CHECK-NOT: {i64 6699318081062747564, i64 [[#]], !"foo"
+; CHECK: !{i64 -2624081020897602054, i64 [[#]], !"main"
; WARN: warning: Pseudo-probe ignored: source module '{{.*}}' is compiled with -fpseudo-probe-for-profiling while destination module '{{.*}}' is not
diff --git a/llvm/test/Transforms/SampleProfile/pseudo-probe-eh.ll b/llvm/test/Transforms/SampleProfile/pseudo-probe-eh.ll
index 697ef44fb7ed..9954914bca43 100644
--- a/llvm/test/Transforms/SampleProfile/pseudo-probe-eh.ll
+++ b/llvm/test/Transforms/SampleProfile/pseudo-probe-eh.ll
@@ -18,7 +18,7 @@ entry:
to label %ret unwind label %lpad
ret:
-; CHECK: call void @llvm.pseudoprobe
+; CHECK-NOT: call void @llvm.pseudoprobe
ret void
lpad: ; preds = %entry
diff --git a/llvm/test/Transforms/SampleProfile/pseudo-probe-invoke.ll b/llvm/test/Transforms/SampleProfile/pseudo-probe-invoke.ll
new file mode 100644
index 000000000000..822ab403dee2
--- /dev/null
+++ b/llvm/test/Transforms/SampleProfile/pseudo-probe-invoke.ll
@@ -0,0 +1,155 @@
+; REQUIRES: x86_64-linux
+; RUN: opt < %s -passes=pseudo-probe -S -o - | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+$__clang_call_terminate = comdat any
+
+@x = dso_local global i32 0, align 4, !dbg !0
+
+; Function Attrs: mustprogress noinline nounwind uwtable
+define dso_local void @_Z3barv() #0 personality ptr @__gxx_personality_v0 !dbg !14 {
+entry:
+; CHECK: call void @llvm.pseudoprobe(i64 -1069303473483922844, i64 1
+ %0 = load volatile i32, ptr @x, align 4, !dbg !17, !tbaa !19
+ %tobool = icmp ne i32 %0, 0, !dbg !17
+ br i1 %tobool, label %if.then, label %if.else, !dbg !23
+
+if.then: ; preds = %entry
+; CHECK: call void @llvm.pseudoprobe(i64 -1069303473483922844, i64 2
+ invoke void @_Z3foov()
+ to label %invoke.cont unwind label %terminate.lpad, !dbg !24
+
+invoke.cont: ; preds = %if.then
+; CHECK-NOT: call void @llvm.pseudoprobe(i64 -1069303473483922844,
+ invoke void @_Z3bazv()
+ to label %invoke.cont1 unwind label %terminate.lpad, !dbg !26
+
+invoke.cont1: ; preds = %invoke.cont
+; CHECK-NOT: call void @llvm.pseudoprobe(i64 -1069303473483922844,
+ br label %if.end, !dbg !27
+
+if.else: ; preds = %entry
+; CHECK: call void @llvm.pseudoprobe(i64 -1069303473483922844, i64 3
+ invoke void @_Z3foov()
+ to label %invoke.cont2 unwind label %terminate.lpad, !dbg !28
+
+invoke.cont2: ; preds = %if.else
+; CHECK-NOT: call void @llvm.pseudoprobe(i64 -1069303473483922844,
+ br label %if.end
+
+if.end: ; preds = %invoke.cont2, %invoke.cont1
+; CHECK: call void @llvm.pseudoprobe(i64 -1069303473483922844, i64 4
+ invoke void @_Z3foov()
+ to label %invoke.cont3 unwind label %terminate.lpad, !dbg !29
+
+invoke.cont3: ; preds = %if.end
+; CHECK-NOT: call void @llvm.pseudoprobe(i64 -1069303473483922844,
+ %1 = load volatile i32, ptr @x, align 4, !dbg !30, !tbaa !19
+ %tobool4 = icmp ne i32 %1, 0, !dbg !30
+ br i1 %tobool4, label %if.then5, label %if.end6, !dbg !32
+
+if.then5: ; preds = %invoke.cont3
+; CHECK: call void @llvm.pseudoprobe(i64 -1069303473483922844, i64 5
+ %2 = load volatile i32, ptr @x, align 4, !dbg !33, !tbaa !19
+ %inc = add nsw i32 %2, 1, !dbg !33
+ store volatile i32 %inc, ptr @x, align 4, !dbg !33, !tbaa !19
+ br label %if.end6, !dbg !35
+
+if.end6: ; preds = %if.then5, %invoke.cont3
+; CHECK: call void @llvm.pseudoprobe(i64 -1069303473483922844, i64 6
+ ret void, !dbg !36
+
+terminate.lpad: ; preds = %if.end, %if.else, %invoke.cont, %if.then
+; CHECK-NOT: call void @llvm.pseudoprobe(i64 -1069303473483922844,
+ %3 = landingpad { ptr, i32 }
+ catch ptr null, !dbg !24
+ %4 = extractvalue { ptr, i32 } %3, 0, !dbg !24
+ call void @__clang_call_terminate(ptr %4) #3, !dbg !24
+ unreachable, !dbg !24
+}
+
+; Function Attrs: mustprogress noinline nounwind uwtable
+define dso_local void @_Z3foov() #0 !dbg !37 {
+entry:
+ ret void, !dbg !38
+}
+
+declare i32 @__gxx_personality_v0(...)
+
+; Function Attrs: noinline noreturn nounwind uwtable
+define linkonce_odr hidden void @__clang_call_terminate(ptr noundef %0) #1 comdat {
+ %2 = call ptr @__cxa_begin_catch(ptr %0) #4
+ call void @_ZSt9terminatev() #3
+ unreachable
+}
+
+declare ptr @__cxa_begin_catch(ptr)
+
+declare void @_ZSt9terminatev()
+
+; Function Attrs: mustprogress noinline nounwind uwtable
+define dso_local void @_Z3bazv() #0 !dbg !39 {
+entry:
+ ret void, !dbg !40
+}
+
+; CHECK: ![[#]] = !{i64 -3270123626113159616, i64 4294967295, !"_Z3bazv"}
+
+attributes #0 = { mustprogress noinline nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #1 = { noinline noreturn nounwind uwtable "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #2 = { mustprogress noinline norecurse nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #3 = { noreturn nounwind }
+attributes #4 = { nounwind }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!7, !8, !9, !10, !11, !12}
+!llvm.ident = !{!13}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "x", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 19.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "test.cpp", directory: "/home", checksumkind: CSK_MD5, checksum: "a4c7b0392f3fd9c8ebb85065159dbb02")
+!4 = !{!0}
+!5 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !6)
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!7 = !{i32 7, !"Dwarf Version", i32 5}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{i32 1, !"wchar_size", i32 4}
+!10 = !{i32 8, !"PIC Level", i32 2}
+!11 = !{i32 7, !"PIE Level", i32 2}
+!12 = !{i32 7, !"uwtable", i32 2}
+!13 = !{!"clang version 19.0.0"}
+!14 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !3, file: !3, line: 4, type: !15, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!15 = !DISubroutineType(types: !16)
+!16 = !{null}
+!17 = !DILocation(line: 5, column: 6, scope: !18)
+!18 = distinct !DILexicalBlock(scope: !14, file: !3, line: 5, column: 6)
+!19 = !{!20, !20, i64 0}
+!20 = !{!"int", !21, i64 0}
+!21 = !{!"omnipotent char", !22, i64 0}
+!22 = !{!"Simple C++ TBAA"}
+!23 = !DILocation(line: 5, column: 6, scope: !14)
+!24 = !DILocation(line: 6, column: 5, scope: !25)
+!25 = distinct !DILexicalBlock(scope: !18, file: !3, line: 5, column: 9)
+!26 = !DILocation(line: 7, column: 5, scope: !25)
+!27 = !DILocation(line: 8, column: 3, scope: !25)
+!28 = !DILocation(line: 9, column: 5, scope: !18)
+!29 = !DILocation(line: 11, column: 3, scope: !14)
+!30 = !DILocation(line: 12, column: 6, scope: !31)
+!31 = distinct !DILexicalBlock(scope: !14, file: !3, line: 12, column: 6)
+!32 = !DILocation(line: 12, column: 6, scope: !14)
+!33 = !DILocation(line: 13, column: 5, scope: !34)
+!34 = distinct !DILexicalBlock(scope: !31, file: !3, line: 12, column: 9)
+!35 = !DILocation(line: 14, column: 5, scope: !34)
+!36 = !DILocation(line: 17, column: 1, scope: !14)
+!37 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !3, file: !3, line: 19, type: !15, scopeLine: 19, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!38 = !DILocation(line: 19, column: 13, scope: !37)
+!39 = distinct !DISubprogram(name: "baz", linkageName: "_Z3bazv", scope: !3, file: !3, line: 18, type: !15, scopeLine: 18, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!40 = !DILocation(line: 18, column: 13, scope: !39)
+!41 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 22, type: !42, scopeLine: 22, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!42 = !DISubroutineType(types: !43)
+!43 = !{!6}
+!44 = !DILocation(line: 23, column: 3, scope: !41)
+!45 = !DILocation(line: 24, column: 1, scope: !41)
--
GitLab
From f2f01f6b03aa81d5bdbf841a88f8853620c6902b Mon Sep 17 00:00:00 2001
From: Jeff Niu
Date: Mon, 1 Apr 2024 13:59:53 -0700
Subject: [PATCH 013/442] [llvm][Support] Use `thread_local` caching for
llvm::get_threadid() query on Apple systems (#87219)
I was profiling our compiler and noticed that `llvm::get_threadid` was
at the top of the hotlist, taking up a surprising 5% (7 seconds) in the
profile trace. It seems that computing this on MacOS systems is
non-trivial, so cache the result in a thread_local.
Co-authored-by: Mehdi Amini
---
llvm/lib/Support/Unix/Threading.inc | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Support/Unix/Threading.inc b/llvm/lib/Support/Unix/Threading.inc
index 55e7dcfa4678..839c00c5ebbf 100644
--- a/llvm/lib/Support/Unix/Threading.inc
+++ b/llvm/lib/Support/Unix/Threading.inc
@@ -115,8 +115,11 @@ uint64_t llvm::get_threadid() {
// Calling "mach_thread_self()" bumps the reference count on the thread
// port, so we need to deallocate it. mach_task_self() doesn't bump the ref
// count.
- thread_port_t Self = mach_thread_self();
- mach_port_deallocate(mach_task_self(), Self);
+ static thread_local thread_port_t Self = [] {
+ thread_port_t InitSelf = mach_thread_self();
+ mach_port_deallocate(mach_task_self(), Self);
+ return InitSelf;
+ }();
return Self;
#elif defined(__FreeBSD__)
return uint64_t(pthread_getthreadid_np());
--
GitLab
From a6caceed8d27d4ebd44c517c3114a36a64ebddfe Mon Sep 17 00:00:00 2001
From: Jordan Rupprecht
Date: Mon, 1 Apr 2024 16:02:12 -0500
Subject: [PATCH 014/442] [lldb] Don't crash when attempting to parse
breakpoint id `N.` as `N.*` (#87263)
We check if the next character after `N.` is `*` before we check its
length. Using `split` on the string is cleaner and less error prone than
using indices with `find` and `substr`.
Note: this does not make `N.` mean anything, it just prevents assertion
failures. `N.` is treated the same as an unrecognized breakpoint name:
```
(lldb) breakpoint enable 1
1 breakpoints enabled.
(lldb) breakpoint enable 1.*
1 breakpoints enabled.
(lldb) breakpoint enable 1.
0 breakpoints enabled.
(lldb) breakpoint enable xyz
0 breakpoints enabled.
```
Found via LLDB fuzzers.
---
lldb/source/Breakpoint/BreakpointIDList.cpp | 48 +++++++++----------
.../TestBreakpointLocations.py | 6 +++
2 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/lldb/source/Breakpoint/BreakpointIDList.cpp b/lldb/source/Breakpoint/BreakpointIDList.cpp
index 851d074e7535..97af1d40eb7a 100644
--- a/lldb/source/Breakpoint/BreakpointIDList.cpp
+++ b/lldb/source/Breakpoint/BreakpointIDList.cpp
@@ -16,6 +16,7 @@
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
using namespace lldb;
using namespace lldb_private;
@@ -111,32 +112,27 @@ llvm::Error BreakpointIDList::FindAndReplaceIDRanges(
} else {
// See if user has specified id.*
llvm::StringRef tmp_str = old_args[i].ref();
- size_t pos = tmp_str.find('.');
- if (pos != llvm::StringRef::npos) {
- llvm::StringRef bp_id_str = tmp_str.substr(0, pos);
- if (BreakpointID::IsValidIDExpression(bp_id_str) &&
- tmp_str[pos + 1] == '*' && tmp_str.size() == (pos + 2)) {
-
- BreakpointSP breakpoint_sp;
- auto bp_id = BreakpointID::ParseCanonicalReference(bp_id_str);
- if (bp_id)
- breakpoint_sp = target->GetBreakpointByID(bp_id->GetBreakpointID());
- if (!breakpoint_sp) {
- new_args.Clear();
- return llvm::createStringError(
- llvm::inconvertibleErrorCode(),
- "'%d' is not a valid breakpoint ID.\n",
- bp_id->GetBreakpointID());
- }
- const size_t num_locations = breakpoint_sp->GetNumLocations();
- for (size_t j = 0; j < num_locations; ++j) {
- BreakpointLocation *bp_loc =
- breakpoint_sp->GetLocationAtIndex(j).get();
- StreamString canonical_id_str;
- BreakpointID::GetCanonicalReference(
- &canonical_id_str, bp_id->GetBreakpointID(), bp_loc->GetID());
- new_args.AppendArgument(canonical_id_str.GetString());
- }
+ auto [prefix, suffix] = tmp_str.split('.');
+ if (suffix == "*" && BreakpointID::IsValidIDExpression(prefix)) {
+
+ BreakpointSP breakpoint_sp;
+ auto bp_id = BreakpointID::ParseCanonicalReference(prefix);
+ if (bp_id)
+ breakpoint_sp = target->GetBreakpointByID(bp_id->GetBreakpointID());
+ if (!breakpoint_sp) {
+ new_args.Clear();
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "'%d' is not a valid breakpoint ID.\n",
+ bp_id->GetBreakpointID());
+ }
+ const size_t num_locations = breakpoint_sp->GetNumLocations();
+ for (size_t j = 0; j < num_locations; ++j) {
+ BreakpointLocation *bp_loc =
+ breakpoint_sp->GetLocationAtIndex(j).get();
+ StreamString canonical_id_str;
+ BreakpointID::GetCanonicalReference(
+ &canonical_id_str, bp_id->GetBreakpointID(), bp_loc->GetID());
+ new_args.AppendArgument(canonical_id_str.GetString());
}
}
}
diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py b/lldb/test/API/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py
index 8930bea619bb..d87e6275f7b5 100644
--- a/lldb/test/API/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py
+++ b/lldb/test/API/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py
@@ -293,6 +293,12 @@ class BreakpointLocationsTestCase(TestBase):
startstr="3 breakpoints enabled.",
)
+ # The 'breakpoint enable 1.' command should not crash.
+ self.expect(
+ "breakpoint enable 1.",
+ startstr="0 breakpoints enabled.",
+ )
+
# The 'breakpoint disable 1.1' command should disable 1 location.
self.expect(
"breakpoint disable 1.1",
--
GitLab
From 03577ced1f55bf96224513f2414bf025d6877fac Mon Sep 17 00:00:00 2001
From: Maksim Panchenko
Date: Mon, 1 Apr 2024 14:11:02 -0700
Subject: [PATCH 015/442] [BOLT][NFC] Fix typo
---
bolt/include/bolt/Core/BinaryFunction.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index 5089f8491280..bc047fefa315 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -1168,7 +1168,7 @@ public:
/// Pass an offset of the entry point in the input binary and a corresponding
/// global symbol to the callback function.
///
- /// Return true of all callbacks returned true, false otherwise.
+ /// Return true if all callbacks returned true, false otherwise.
bool forEachEntryPoint(EntryPointCallbackTy Callback) const;
/// Return MC symbol associated with the end of the function.
--
GitLab
From 70e189fbc96909d3841dd2bca4a2909345cd826f Mon Sep 17 00:00:00 2001
From: Nick Desaulniers
Date: Mon, 1 Apr 2024 14:13:56 -0700
Subject: [PATCH 016/442] [libc] fixup ftello test (#87282)
Use a seek offset that fits within the file size.
This was missed in presubmit because the FILE based stdio tests aren't
run in
overlay mode; fullbuild is not tested in presubmit.
WRITE_SIZE == 11, so using a value of 42 for offseto would cause the
expression
`WRITE_SIZE - offseto` to evaluate to -31 as an unsigned 64b integer
(18446744073709551585ULL).
Fixes #86928
---
libc/test/src/stdio/ftell_test.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/test/src/stdio/ftell_test.cpp b/libc/test/src/stdio/ftell_test.cpp
index 68a969ed0c30..62745e2194be 100644
--- a/libc/test/src/stdio/ftell_test.cpp
+++ b/libc/test/src/stdio/ftell_test.cpp
@@ -39,7 +39,7 @@ protected:
// still return the correct effective offset.
ASSERT_EQ(size_t(LIBC_NAMESPACE::ftell(file)), WRITE_SIZE);
- off_t offseto = 42;
+ off_t offseto = 5;
ASSERT_EQ(0, LIBC_NAMESPACE::fseeko(file, offseto, SEEK_SET));
ASSERT_EQ(LIBC_NAMESPACE::ftello(file), offseto);
ASSERT_EQ(0, LIBC_NAMESPACE::fseeko(file, -offseto, SEEK_END));
--
GitLab
From 6b136ce738d1acc96d926d7999419867dea16961 Mon Sep 17 00:00:00 2001
From: Tom Stellard
Date: Mon, 1 Apr 2024 14:35:39 -0700
Subject: [PATCH 017/442] [workflows] issue-write: Exit early if there are no
comments (#87114)
This will eliminate some unnecessary REST API calls.
---
.github/workflows/issue-write.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/issue-write.yml b/.github/workflows/issue-write.yml
index 02a5f7c213e8..f5b84fec17a7 100644
--- a/.github/workflows/issue-write.yml
+++ b/.github/workflows/issue-write.yml
@@ -31,7 +31,7 @@ jobs:
script: |
var fs = require('fs');
const comments = JSON.parse(fs.readFileSync('./comments'));
- if (!comments) {
+ if (!comments || comments.length == 0) {
return;
}
--
GitLab
From 0478adc97e1a4018d866520cb149b6e6c2a9101a Mon Sep 17 00:00:00 2001
From: Fangrui Song
Date: Mon, 1 Apr 2024 14:58:28 -0700
Subject: [PATCH 018/442] [Object,ELFTypes] Remove TargetEndianness
Finish the rename by #86604
---
llvm/include/llvm/Object/ELFTypes.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h
index 4617b70a2f12..4ab23e4ea81b 100644
--- a/llvm/include/llvm/Object/ELFTypes.h
+++ b/llvm/include/llvm/Object/ELFTypes.h
@@ -51,7 +51,6 @@ private:
using packed = support::detail::packed_endian_specific_integral;
public:
- static const endianness TargetEndianness = E;
static const endianness Endianness = E;
static const bool Is64Bits = Is64;
--
GitLab
From 1d5e5f4d3c68e63ced47ee9b17d62fb995aa1e62 Mon Sep 17 00:00:00 2001
From: Michael Maitland
Date: Mon, 1 Apr 2024 15:06:10 -0700
Subject: [PATCH 019/442] [GISEL][NFC] Fix comment for widenScalarToNextPow2
The docstring for this function incorrectly specified when a widening is
not performed. This patch adds the additional specification for what
happens when the type size is a power of two but it is less than MinSize.
---
llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index 6afaea3f3fc5..82e713f30ea3 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
@@ -879,7 +879,8 @@ public:
}
/// Widen the scalar to the next power of two that is at least MinSize.
- /// No effect if the type is not a scalar or is a power of two.
+ /// No effect if the type is a power of two, except if the type is smaller
+ /// than MinSize, or if the type is a vector type.
LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx,
unsigned MinSize = 0) {
using namespace LegalityPredicates;
--
GitLab
From 1e15371dd8843dfc52b9435afaa133997c1773d8 Mon Sep 17 00:00:00 2001
From: Mingming Liu
Date: Mon, 1 Apr 2024 15:14:49 -0700
Subject: [PATCH 020/442] [ThinLTO][TypeProf] Implement vtable def import
(#79381)
Add annotated vtable GUID as referenced variables in per function
summary, and update bitcode writer to create value-ids for these
referenced vtables.
- This is the part3 of type profiling work, and described in the "Virtual Table Definition Import" [1] section of the
RFC.
[1] https://github.com/llvm/llvm-project/pull/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
---
llvm/include/llvm/ProfileData/InstrProf.h | 12 +++-
.../IndirectCallPromotionAnalysis.cpp | 4 ++
llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 20 ++++++
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 13 +++-
llvm/lib/ProfileData/InstrProf.cpp | 70 +++++++++++++------
.../thinlto-func-summary-vtableref-pgo.ll | 37 ++++++----
6 files changed, 120 insertions(+), 36 deletions(-)
diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h
index fd66c4ed948f..eb3c10bcba1c 100644
--- a/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/llvm/include/llvm/ProfileData/InstrProf.h
@@ -283,7 +283,7 @@ void annotateValueSite(Module &M, Instruction &Inst,
/// Extract the value profile data from \p Inst which is annotated with
/// value profile meta data. Return false if there is no value data annotated,
-/// otherwise return true.
+/// otherwise return true.
bool getValueProfDataFromInst(const Instruction &Inst,
InstrProfValueKind ValueKind,
uint32_t MaxNumValueData,
@@ -291,6 +291,16 @@ bool getValueProfDataFromInst(const Instruction &Inst,
uint32_t &ActualNumValueData, uint64_t &TotalC,
bool GetNoICPValue = false);
+/// Extract the value profile data from \p Inst and returns them if \p Inst is
+/// annotated with value profile data. Returns nullptr otherwise. It's similar
+/// to `getValueProfDataFromInst` above except that an array is allocated only
+/// after a preliminary checking that the value profiles of kind `ValueKind`
+/// exist.
+std::unique_ptr
+getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind,
+ uint32_t MaxNumValueData, uint32_t &ActualNumValueData,
+ uint64_t &TotalC, bool GetNoICPValue = false);
+
inline StringRef getPGOFuncNameMetadataName() { return "PGOFuncName"; }
/// Return the PGOFuncName meta data associated with a function.
diff --git a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
index ebfa1c8fc08e..ab53717eb889 100644
--- a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
+++ b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
@@ -45,6 +45,10 @@ static cl::opt
cl::desc("Max number of promotions for a single indirect "
"call callsite"));
+cl::opt MaxNumVTableAnnotations(
+ "icp-max-num-vtables", cl::init(6), cl::Hidden,
+ cl::desc("Max number of vtables annotated for a vtable load instruction."));
+
ICallPromotionAnalysis::ICallPromotionAnalysis() {
ValueDataArray = std::make_unique(MaxNumPromotions);
}
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index 1f15e9478324..3ad0bab827a5 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -82,6 +82,8 @@ static cl::opt ModuleSummaryDotFile(
extern cl::opt ScalePartialSampleProfileWorkingSetSize;
+extern cl::opt MaxNumVTableAnnotations;
+
// Walk through the operands of a given User via worklist iteration and populate
// the set of GlobalValue references encountered. Invoked either on an
// Instruction or a GlobalVariable (which walks its initializer).
@@ -124,6 +126,24 @@ static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
Worklist.push_back(Operand);
}
}
+
+ const Instruction *I = dyn_cast(CurUser);
+ if (I) {
+ uint32_t ActualNumValueData = 0;
+ uint64_t TotalCount = 0;
+ // MaxNumVTableAnnotations is the maximum number of vtables annotated on
+ // the instruction.
+ auto ValueDataArray =
+ getValueProfDataFromInst(*I, IPVK_VTableTarget, MaxNumVTableAnnotations,
+ ActualNumValueData, TotalCount);
+
+ if (ValueDataArray.get()) {
+ for (uint32_t j = 0; j < ActualNumValueData; j++) {
+ RefEdges.insert(Index.getOrInsertValueInfo(/* VTableGUID = */
+ ValueDataArray[j].Value));
+ }
+ }
+ }
return HasBlockAddress;
}
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 221eeaae6e2b..dd554e422516 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -203,7 +203,7 @@ public:
for (const auto &GUIDSummaryLists : *Index)
// Examine all summaries for this GUID.
for (auto &Summary : GUIDSummaryLists.second.SummaryList)
- if (auto FS = dyn_cast(Summary.get()))
+ if (auto FS = dyn_cast(Summary.get())) {
// For each call in the function summary, see if the call
// is to a GUID (which means it is for an indirect call,
// otherwise we would have a Value for it). If so, synthesize
@@ -211,6 +211,15 @@ public:
for (auto &CallEdge : FS->calls())
if (!CallEdge.first.haveGVs() || !CallEdge.first.getValue())
assignValueId(CallEdge.first.getGUID());
+
+ // For each referenced variables in the function summary, see if the
+ // variable is represented by a GUID (as opposed to a symbol to
+ // declarations or definitions in the module). If so, synthesize a
+ // value id.
+ for (auto &RefEdge : FS->refs())
+ if (!RefEdge.haveGVs() || !RefEdge.getValue())
+ assignValueId(RefEdge.getGUID());
+ }
}
protected:
@@ -4188,7 +4197,7 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(
NameVals.push_back(SpecialRefCnts.second); // worefcnt
for (auto &RI : FS->refs())
- NameVals.push_back(VE.getValueID(RI.getValue()));
+ NameVals.push_back(getValueId(RI));
const bool UseRelBFRecord =
WriteRelBFToSummary && !F.hasProfileData() &&
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 90c3cfc45b98..95f900d0fff1 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1271,46 +1271,44 @@ void annotateValueSite(Module &M, Instruction &Inst,
Inst.setMetadata(LLVMContext::MD_prof, MDNode::get(Ctx, Vals));
}
-bool getValueProfDataFromInst(const Instruction &Inst,
- InstrProfValueKind ValueKind,
- uint32_t MaxNumValueData,
- InstrProfValueData ValueData[],
- uint32_t &ActualNumValueData, uint64_t &TotalC,
- bool GetNoICPValue) {
+MDNode *mayHaveValueProfileOfKind(const Instruction &Inst,
+ InstrProfValueKind ValueKind) {
MDNode *MD = Inst.getMetadata(LLVMContext::MD_prof);
if (!MD)
- return false;
+ return nullptr;
- unsigned NOps = MD->getNumOperands();
+ if (MD->getNumOperands() < 5)
+ return nullptr;
- if (NOps < 5)
- return false;
-
- // Operand 0 is a string tag "VP":
MDString *Tag = cast(MD->getOperand(0));
- if (!Tag)
- return false;
-
- if (!Tag->getString().equals("VP"))
- return false;
+ if (!Tag || !Tag->getString().equals("VP"))
+ return nullptr;
// Now check kind:
ConstantInt *KindInt = mdconst::dyn_extract(MD->getOperand(1));
if (!KindInt)
- return false;
+ return nullptr;
if (KindInt->getZExtValue() != ValueKind)
- return false;
+ return nullptr;
+
+ return MD;
+}
+static bool getValueProfDataFromInstImpl(const MDNode *const MD,
+ const uint32_t MaxNumDataWant,
+ InstrProfValueData ValueData[],
+ uint32_t &ActualNumValueData,
+ uint64_t &TotalC, bool GetNoICPValue) {
+ const unsigned NOps = MD->getNumOperands();
// Get total count
ConstantInt *TotalCInt = mdconst::dyn_extract(MD->getOperand(2));
if (!TotalCInt)
return false;
TotalC = TotalCInt->getZExtValue();
-
ActualNumValueData = 0;
for (unsigned I = 3; I < NOps; I += 2) {
- if (ActualNumValueData >= MaxNumValueData)
+ if (ActualNumValueData >= MaxNumDataWant)
break;
ConstantInt *Value = mdconst::dyn_extract(MD->getOperand(I));
ConstantInt *Count =
@@ -1327,6 +1325,36 @@ bool getValueProfDataFromInst(const Instruction &Inst,
return true;
}
+std::unique_ptr
+getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind,
+ uint32_t MaxNumValueData, uint32_t &ActualNumValueData,
+ uint64_t &TotalC, bool GetNoICPValue) {
+ MDNode *MD = mayHaveValueProfileOfKind(Inst, ValueKind);
+ if (!MD)
+ return nullptr;
+ auto ValueDataArray = std::make_unique(MaxNumValueData);
+ if (!getValueProfDataFromInstImpl(MD, MaxNumValueData, ValueDataArray.get(),
+ ActualNumValueData, TotalC, GetNoICPValue))
+ return nullptr;
+ return ValueDataArray;
+}
+
+// FIXME: Migrate existing callers to the function above that returns an
+// array.
+bool getValueProfDataFromInst(const Instruction &Inst,
+ InstrProfValueKind ValueKind,
+ uint32_t MaxNumValueData,
+ InstrProfValueData ValueData[],
+ uint32_t &ActualNumValueData, uint64_t &TotalC,
+ bool GetNoICPValue) {
+ MDNode *MD = mayHaveValueProfileOfKind(Inst, ValueKind);
+ if (!MD)
+ return false;
+ return getValueProfDataFromInstImpl(MD, MaxNumValueData, ValueData,
+ ActualNumValueData, TotalC,
+ GetNoICPValue);
+}
+
MDNode *getPGOFuncNameMetadata(const Function &F) {
return F.getMetadata(getPGOFuncNameMetadataName());
}
diff --git a/llvm/test/Bitcode/thinlto-func-summary-vtableref-pgo.ll b/llvm/test/Bitcode/thinlto-func-summary-vtableref-pgo.ll
index 78b175caca85..ba3ce9a75ee8 100644
--- a/llvm/test/Bitcode/thinlto-func-summary-vtableref-pgo.ll
+++ b/llvm/test/Bitcode/thinlto-func-summary-vtableref-pgo.ll
@@ -1,20 +1,31 @@
-; RUN: opt -module-summary %s -o %t.o
+; Promote at most one function and annotate at most one vtable.
+; As a result, only one value (of each relevant kind) shows up in the function
+; summary.
+
+; RUN: opt -module-summary -icp-max-num-vtables=1 -icp-max-prom=1 %s -o %t.o
; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
; RUN: llvm-dis -o - %t.o | FileCheck %s --check-prefix=DIS
-
+; Round trip it through llvm-as
+; RUN: llvm-dis -o - %t.o | llvm-as -o - | llvm-dis -o - | FileCheck %s --check-prefix=DIS
; CHECK:
; CHECK-NEXT:
+; The `VALUE_GUID` below represents the "_ZTV4Base" referenced by the instruction
+; that loads vtable pointers.
+; CHECK-NEXT:
; The `VALUE_GUID` below represents the "_ZN4Base4funcEv" referenced by the
; indirect call instruction.
-; CHECK-NEXT:
+; CHECK-NEXT:
+; NOTE vtables and functions from Derived class is dropped because
+; `-icp-max-num-vtables` and `-icp-max-prom` are both set to one.
; has the format [valueid, flags, instcount, funcflags,
; numrefs, rorefcnt, worefcnt,
+; m x valueid,
; n x (valueid, hotness+tailcall)]
-; CHECK-NEXT:
+; CHECK-NEXT:
; CHECK-NEXT:
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -31,7 +42,6 @@ define i32 @_Z4testP4Base(ptr %0) !prof !15 {
!llvm.module.flags = !{!1}
-
!1 = !{i32 1, !"ProfileSummary", !2}
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
!3 = !{!"ProfileFormat", !"InstrProf"}
@@ -48,14 +58,17 @@ define i32 @_Z4testP4Base(ptr %0) !prof !15 {
!14 = !{i32 999999, i64 1, i32 2}
!15 = !{!"function_entry_count", i32 150}
-; 1960855528937986108 is the MD5 hash of _ZTV4Base
-!16 = !{!"VP", i32 2, i64 1600, i64 1960855528937986108, i64 1600}
-; 5459407273543877811 is the MD5 hash of _ZN4Base4funcEv
-!17 = !{!"VP", i32 0, i64 1600, i64 5459407273543877811, i64 1600}
+; 1960855528937986108 is the MD5 hash of _ZTV4Base, and
+; 13870436605473471591 is the MD5 hash of _ZTV7Derived
+!16 = !{!"VP", i32 2, i64 150, i64 1960855528937986108, i64 100, i64 13870436605473471591, i64 50}
+; 5459407273543877811 is the MD5 hash of _ZN4Base4funcEv, and
+; 6174874150489409711 is the MD5 hash of _ZN7Derived4funcEv
+!17 = !{!"VP", i32 0, i64 150, i64 5459407273543877811, i64 100, i64 6174874150489409711, i64 50}
; ModuleSummaryIndex stores map in std::map; so
; global value summares are printed out in the order that gv's guid increases.
; DIS: ^0 = module: (path: "{{.*}}", hash: (0, 0, 0, 0, 0))
-; DIS: ^1 = gv: (guid: 5459407273543877811)
-; DIS: ^2 = gv: (name: "_Z4testP4Base", summaries: (function: (module: ^0, flags: (linkage: external, visibility: default, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), insts: 4, funcFlags: (readNone: 0, readOnly: 0, noRecurse: 0, returnDoesNotAlias: 0, noInline: 0, alwaysInline: 0, noUnwind: 0, mayThrow: 0, hasUnknownCall: 1, mustBeUnreachable: 0), calls: ((callee: ^1, hotness: hot))))) ; guid = 15857150948103218965
-; DIS: ^3 = blockcount: 0
+; DIS: ^1 = gv: (guid: 1960855528937986108)
+; DIS: ^2 = gv: (guid: 5459407273543877811)
+; DIS: ^3 = gv: (name: "_Z4testP4Base", summaries: (function: (module: ^0, flags: (linkage: external, visibility: default, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), insts: 4, funcFlags: (readNone: 0, readOnly: 0, noRecurse: 0, returnDoesNotAlias: 0, noInline: 0, alwaysInline: 0, noUnwind: 0, mayThrow: 0, hasUnknownCall: 1, mustBeUnreachable: 0), calls: ((callee: ^2, hotness: hot)), refs: (readonly ^1)))) ; guid = 15857150948103218965
+; DIS: ^4 = blockcount: 0
--
GitLab
From 649f9603a2da82a32830ce1dc7ce5825d3766a1d Mon Sep 17 00:00:00 2001
From: Tom Stellard
Date: Mon, 1 Apr 2024 15:17:24 -0700
Subject: [PATCH 021/442] [workflows] issue-write: Avoid race condition when PR
branch is deleted (#87118)
Fixes #87102 .
---
.github/workflows/issue-write.yml | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/.github/workflows/issue-write.yml b/.github/workflows/issue-write.yml
index f5b84fec17a7..4a564a5076ba 100644
--- a/.github/workflows/issue-write.yml
+++ b/.github/workflows/issue-write.yml
@@ -77,6 +77,15 @@ jobs:
}
const gql_result = await github.graphql(gql_query, gql_variables);
console.log(gql_result);
+ // If the branch for the PR was deleted before this job has a chance
+ // to run, then the ref will be null. This can happen if someone:
+ // 1. Rebase the PR, which triggers some workflow.
+ // 2. Immediately merges the PR and deletes the branch.
+ // 3. The workflow finishes and triggers this job.
+ if (!gql_result.repository.ref) {
+ console.log("Ref has been deleted");
+ return;
+ }
console.log(gql_result.repository.ref.associatedPullRequests.nodes);
var pr_number = 0;
--
GitLab
From f2a87b07e7fe1892a11ee9424d22dbaec5de5b5b Mon Sep 17 00:00:00 2001
From: Joseph Huber
Date: Mon, 1 Apr 2024 17:26:20 -0500
Subject: [PATCH 022/442] [OpenMP] Use loaded offloading toolchains to add
libraries (#87108)
Summary:
We want to pass these GPU libraries by default if a certain offloading
toolchain is loaded for OpenMP. Previously I parsed this from the
arguments because it's only available in the compilation. This doesn't
really work for `native` and it's extra effort, so this patch just
passes in the `Compilation` as an extr argument and uses that. Tests
should be unaffected.
---
clang/lib/Driver/ToolChains/CommonArgs.cpp | 58 ++++++++--------------
clang/lib/Driver/ToolChains/CommonArgs.h | 4 +-
clang/lib/Driver/ToolChains/Darwin.cpp | 2 +-
clang/lib/Driver/ToolChains/DragonFly.cpp | 2 +-
clang/lib/Driver/ToolChains/FreeBSD.cpp | 2 +-
clang/lib/Driver/ToolChains/Gnu.cpp | 2 +-
clang/lib/Driver/ToolChains/Haiku.cpp | 2 +-
clang/lib/Driver/ToolChains/NetBSD.cpp | 2 +-
clang/lib/Driver/ToolChains/OpenBSD.cpp | 2 +-
clang/lib/Driver/ToolChains/Solaris.cpp | 2 +-
10 files changed, 32 insertions(+), 46 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index ace4fb99581e..62a53b85ce09 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1075,14 +1075,14 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
/// Adds the '-lcgpu' and '-lmgpu' libraries to the compilation to include the
/// LLVM C library for GPUs.
-static void addOpenMPDeviceLibC(const ToolChain &TC, const ArgList &Args,
+static void addOpenMPDeviceLibC(const Compilation &C, const ArgList &Args,
ArgStringList &CmdArgs) {
if (Args.hasArg(options::OPT_nogpulib) || Args.hasArg(options::OPT_nolibc))
return;
// Check the resource directory for the LLVM libc GPU declarations. If it's
// found we can assume that LLVM was built with support for the GPU libc.
- SmallString<256> LibCDecls(TC.getDriver().ResourceDir);
+ SmallString<256> LibCDecls(C.getDriver().ResourceDir);
llvm::sys::path::append(LibCDecls, "include", "llvm_libc_wrappers",
"llvm-libc-decls");
bool HasLibC = llvm::sys::fs::exists(LibCDecls) &&
@@ -1090,38 +1090,23 @@ static void addOpenMPDeviceLibC(const ToolChain &TC, const ArgList &Args,
if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC))
return;
- // We don't have access to the offloading toolchains here, so determine from
- // the arguments if we have any active NVPTX or AMDGPU toolchains.
- llvm::DenseSet Libraries;
- if (const Arg *Targets = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {
- if (llvm::any_of(Targets->getValues(),
- [](auto S) { return llvm::Triple(S).isAMDGPU(); })) {
- Libraries.insert("-lcgpu-amdgpu");
- Libraries.insert("-lmgpu-amdgpu");
- }
- if (llvm::any_of(Targets->getValues(),
- [](auto S) { return llvm::Triple(S).isNVPTX(); })) {
- Libraries.insert("-lcgpu-nvptx");
- Libraries.insert("-lmgpu-nvptx");
- }
- }
+ SmallVector ToolChains;
+ auto TCRange = C.getOffloadToolChains(Action::OFK_OpenMP);
+ for (auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
+ ToolChains.push_back(TI->second);
- for (StringRef Arch : Args.getAllArgValues(options::OPT_offload_arch_EQ)) {
- if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) {
- return IsAMDGpuArch(StringToCudaArch(Str));
- })) {
- Libraries.insert("-lcgpu-amdgpu");
- Libraries.insert("-lmgpu-amdgpu");
- }
- if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) {
- return IsNVIDIAGpuArch(StringToCudaArch(Str));
- })) {
- Libraries.insert("-lcgpu-nvptx");
- Libraries.insert("-lmgpu-nvptx");
- }
+ if (llvm::any_of(ToolChains, [](const ToolChain *TC) {
+ return TC->getTriple().isAMDGPU();
+ })) {
+ CmdArgs.push_back("-lcgpu-amdgpu");
+ CmdArgs.push_back("-lmgpu-amdgpu");
+ }
+ if (llvm::any_of(ToolChains, [](const ToolChain *TC) {
+ return TC->getTriple().isNVPTX();
+ })) {
+ CmdArgs.push_back("-lcgpu-nvptx");
+ CmdArgs.push_back("-lmgpu-nvptx");
}
-
- llvm::append_range(CmdArgs, Libraries);
}
void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
@@ -1153,9 +1138,10 @@ void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
}
}
-bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
- const ArgList &Args, bool ForceStaticHostRuntime,
- bool IsOffloadingHost, bool GompNeedsRT) {
+bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs,
+ const ToolChain &TC, const ArgList &Args,
+ bool ForceStaticHostRuntime, bool IsOffloadingHost,
+ bool GompNeedsRT) {
if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
options::OPT_fno_openmp, false))
return false;
@@ -1196,7 +1182,7 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
CmdArgs.push_back("-lomptarget.devicertl");
if (IsOffloadingHost)
- addOpenMPDeviceLibC(TC, Args, CmdArgs);
+ addOpenMPDeviceLibC(C, Args, CmdArgs);
addArchSpecificRPath(TC, Args, CmdArgs);
addOpenMPRuntimeLibraryPath(TC, Args, CmdArgs);
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index bb37be4bd6ea..5581905db311 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -111,8 +111,8 @@ void addOpenMPRuntimeLibraryPath(const ToolChain &TC,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
/// Returns true, if an OpenMP runtime has been added.
-bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC,
- const llvm::opt::ArgList &Args,
+bool addOpenMPRuntime(const Compilation &C, llvm::opt::ArgStringList &CmdArgs,
+ const ToolChain &TC, const llvm::opt::ArgList &Args,
bool ForceStaticHostRuntime = false,
bool IsOffloadingHost = false, bool GompNeedsRT = false);
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index c7682c7f1d33..caf6c4a444fd 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -686,7 +686,7 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
- addOpenMPRuntime(CmdArgs, getToolChain(), Args);
+ addOpenMPRuntime(C, CmdArgs, getToolChain(), Args);
if (isObjCRuntimeLinked(Args) &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
diff --git a/clang/lib/Driver/ToolChains/DragonFly.cpp b/clang/lib/Driver/ToolChains/DragonFly.cpp
index b59a172bd6ae..1dbc46763c11 100644
--- a/clang/lib/Driver/ToolChains/DragonFly.cpp
+++ b/clang/lib/Driver/ToolChains/DragonFly.cpp
@@ -136,7 +136,7 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;
- addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
+ addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);
if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp
index c5757ddebb0f..a8ee6540001e 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -295,7 +295,7 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
!Args.hasArg(options::OPT_static);
- addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
+ addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);
if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index a9c9d2475809..dedbfac6cb25 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -598,7 +598,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// FIXME: Only pass GompNeedsRT = true for platforms with libgomp that
// require librt. Most modern Linux platforms do, but some may not.
- if (addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP,
+ if (addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP,
JA.isHostOffloading(Action::OFK_OpenMP),
/* GompNeedsRT= */ true))
// OpenMP runtimes implies pthreads when using the GNU toolchain.
diff --git a/clang/lib/Driver/ToolChains/Haiku.cpp b/clang/lib/Driver/ToolChains/Haiku.cpp
index 30464e2229e6..346652a7e4bd 100644
--- a/clang/lib/Driver/ToolChains/Haiku.cpp
+++ b/clang/lib/Driver/ToolChains/Haiku.cpp
@@ -107,7 +107,7 @@ void haiku::Linker::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_r)) {
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;
- addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
+ addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);
if (D.CCCIsCXX() && ToolChain.ShouldLinkCXXStdlib(Args))
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp
index 0eec8fddabd5..d54f22882949 100644
--- a/clang/lib/Driver/ToolChains/NetBSD.cpp
+++ b/clang/lib/Driver/ToolChains/NetBSD.cpp
@@ -311,7 +311,7 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_r)) {
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;
- addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
+ addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);
if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp
index 6da6728585df..e20d9fb1cfc4 100644
--- a/clang/lib/Driver/ToolChains/OpenBSD.cpp
+++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp
@@ -221,7 +221,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_r)) {
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;
- addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
+ addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);
if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp
index 5d7f0ae2a392..7126e018ca5b 100644
--- a/clang/lib/Driver/ToolChains/Solaris.cpp
+++ b/clang/lib/Driver/ToolChains/Solaris.cpp
@@ -211,7 +211,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
!Args.hasArg(options::OPT_static);
- addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
+ addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);
if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
--
GitLab
From 9df19ce40281551bd348b262a131085cf98dadf5 Mon Sep 17 00:00:00 2001
From: David Blaikie
Date: Mon, 1 Apr 2024 23:07:01 +0000
Subject: [PATCH 023/442] Add uncovered enums in switches caused by
9434c083475e42f47383f3067fe2a155db5c6a30
These are probably actually unreachable - perhaps an lldb developer
would be interested in rephrasing this change to move the new cases into
some unreachable/unsupported bucket, rather than my half-hearted guess
at what the desired behavior would be (completely untested, because
they're probably untestable/unreachable - maybe debugging from modules?)
---
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index ebcc3bc99a80..4a1c8d576552 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -4097,6 +4097,8 @@ TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) {
return lldb::eTypeClassArray;
case clang::Type::DependentSizedArray:
return lldb::eTypeClassArray;
+ case clang::Type::ArrayParameter:
+ return lldb::eTypeClassArray;
case clang::Type::DependentSizedExtVector:
return lldb::eTypeClassVector;
case clang::Type::DependentVector:
@@ -4776,6 +4778,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::Type::IncompleteArray:
case clang::Type::VariableArray:
+ case clang::Type::ArrayParameter:
break;
case clang::Type::ConstantArray:
@@ -5109,6 +5112,7 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::Type::IncompleteArray:
case clang::Type::VariableArray:
+ case clang::Type::ArrayParameter:
break;
case clang::Type::ConstantArray:
--
GitLab
From 1079fc4f543c42bb09a33d2d79d90edd9c0bac91 Mon Sep 17 00:00:00 2001
From: Ivan Butygin
Date: Tue, 2 Apr 2024 02:43:04 +0300
Subject: [PATCH 024/442] [mlir][pass] Add `errorHandler` param to
`Pass::initializeOptions` (#87289)
There is no good way to report detailed errors from inside
`Pass::initializeOptions` function as context may not be available at
this point and writing directly to `llvm::errs()` is not composable.
See
https://github.com/llvm/llvm-project/pull/87166#discussion_r1546426763
* Add error handler callback to `Pass::initializeOptions`
* Update `PassOptions::parseFromString` to support custom error stream
instead of using `llvm::errs()` directly.
* Update default `Pass::initializeOptions` implementation to propagate
error string from `parseFromString` to new error handler.
* Update `MapMemRefStorageClassPass` to report error details using new
API.
---
mlir/include/mlir/Pass/Pass.h | 4 +++-
mlir/include/mlir/Pass/PassOptions.h | 3 ++-
.../MemRefToSPIRV/MapMemRefStorageClassPass.cpp | 8 +++++---
mlir/lib/Pass/Pass.cpp | 12 ++++++++++--
mlir/lib/Pass/PassRegistry.cpp | 7 ++++---
mlir/lib/Transforms/InlinerPass.cpp | 10 +++++++---
.../Dialect/Transform/test-pass-application.mlir | 1 +
7 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/mlir/include/mlir/Pass/Pass.h b/mlir/include/mlir/Pass/Pass.h
index 070e0cad3878..0f50f3064f17 100644
--- a/mlir/include/mlir/Pass/Pass.h
+++ b/mlir/include/mlir/Pass/Pass.h
@@ -114,7 +114,9 @@ public:
/// Derived classes may override this method to hook into the point at which
/// options are initialized, but should generally always invoke this base
/// class variant.
- virtual LogicalResult initializeOptions(StringRef options);
+ virtual LogicalResult
+ initializeOptions(StringRef options,
+ function_ref errorHandler);
/// Prints out the pass in the textual representation of pipelines. If this is
/// an adaptor pass, print its pass managers.
diff --git a/mlir/include/mlir/Pass/PassOptions.h b/mlir/include/mlir/Pass/PassOptions.h
index 6717a3585d12..3a5e3224133e 100644
--- a/mlir/include/mlir/Pass/PassOptions.h
+++ b/mlir/include/mlir/Pass/PassOptions.h
@@ -293,7 +293,8 @@ public:
/// Parse options out as key=value pairs that can then be handed off to the
/// `llvm::cl` command line passing infrastructure. Everything is space
/// separated.
- LogicalResult parseFromString(StringRef options);
+ LogicalResult parseFromString(StringRef options,
+ raw_ostream &errorStream = llvm::errs());
/// Print the options held by this struct in a form that can be parsed via
/// 'parseFromString'.
diff --git a/mlir/lib/Conversion/MemRefToSPIRV/MapMemRefStorageClassPass.cpp b/mlir/lib/Conversion/MemRefToSPIRV/MapMemRefStorageClassPass.cpp
index 76dab8ee4ac3..4cbc3dfdae22 100644
--- a/mlir/lib/Conversion/MemRefToSPIRV/MapMemRefStorageClassPass.cpp
+++ b/mlir/lib/Conversion/MemRefToSPIRV/MapMemRefStorageClassPass.cpp
@@ -272,14 +272,16 @@ public:
const spirv::MemorySpaceToStorageClassMap &memorySpaceMap)
: memorySpaceMap(memorySpaceMap) {}
- LogicalResult initializeOptions(StringRef options) override {
- if (failed(Pass::initializeOptions(options)))
+ LogicalResult initializeOptions(
+ StringRef options,
+ function_ref errorHandler) override {
+ if (failed(Pass::initializeOptions(options, errorHandler)))
return failure();
if (clientAPI == "opencl")
memorySpaceMap = spirv::mapMemorySpaceToOpenCLStorageClass;
else if (clientAPI != "vulkan")
- return failure();
+ return errorHandler(llvm::Twine("Invalid clienAPI: ") + clientAPI);
return success();
}
diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp
index 3fb05e538666..57a6c20141d2 100644
--- a/mlir/lib/Pass/Pass.cpp
+++ b/mlir/lib/Pass/Pass.cpp
@@ -60,8 +60,16 @@ Operation *PassExecutionAction::getOp() const {
void Pass::anchor() {}
/// Attempt to initialize the options of this pass from the given string.
-LogicalResult Pass::initializeOptions(StringRef options) {
- return passOptions.parseFromString(options);
+LogicalResult Pass::initializeOptions(
+ StringRef options,
+ function_ref errorHandler) {
+ std::string errStr;
+ llvm::raw_string_ostream os(errStr);
+ if (failed(passOptions.parseFromString(options, os))) {
+ os.flush();
+ return errorHandler(errStr);
+ }
+ return success();
}
/// Copy the option values from 'other', which is another instance of this
diff --git a/mlir/lib/Pass/PassRegistry.cpp b/mlir/lib/Pass/PassRegistry.cpp
index b0c314369190..f8149673a409 100644
--- a/mlir/lib/Pass/PassRegistry.cpp
+++ b/mlir/lib/Pass/PassRegistry.cpp
@@ -40,7 +40,7 @@ buildDefaultRegistryFn(const PassAllocatorFunction &allocator) {
return [=](OpPassManager &pm, StringRef options,
function_ref errorHandler) {
std::unique_ptr pass = allocator();
- LogicalResult result = pass->initializeOptions(options);
+ LogicalResult result = pass->initializeOptions(options, errorHandler);
std::optional pmOpName = pm.getOpName();
std::optional passOpName = pass->getOpName();
@@ -280,7 +280,8 @@ parseNextArg(StringRef options) {
llvm_unreachable("unexpected control flow in pass option parsing");
}
-LogicalResult detail::PassOptions::parseFromString(StringRef options) {
+LogicalResult detail::PassOptions::parseFromString(StringRef options,
+ raw_ostream &errorStream) {
// NOTE: `options` is modified in place to always refer to the unprocessed
// part of the string.
while (!options.empty()) {
@@ -291,7 +292,7 @@ LogicalResult detail::PassOptions::parseFromString(StringRef options) {
auto it = OptionsMap.find(key);
if (it == OptionsMap.end()) {
- llvm::errs() << ": no such option " << key << "\n";
+ errorStream << ": no such option " << key << "\n";
return failure();
}
if (llvm::cl::ProvidePositionalOption(it->second, value, 0))
diff --git a/mlir/lib/Transforms/InlinerPass.cpp b/mlir/lib/Transforms/InlinerPass.cpp
index 9a7d5403a95d..43ca5cac8b76 100644
--- a/mlir/lib/Transforms/InlinerPass.cpp
+++ b/mlir/lib/Transforms/InlinerPass.cpp
@@ -64,7 +64,9 @@ private:
/// Derived classes may override this method to hook into the point at which
/// options are initialized, but should generally always invoke this base
/// class variant.
- LogicalResult initializeOptions(StringRef options) override;
+ LogicalResult initializeOptions(
+ StringRef options,
+ function_ref errorHandler) override;
/// Inliner configuration parameters created from the pass options.
InlinerConfig config;
@@ -153,8 +155,10 @@ void InlinerPass::runOnOperation() {
return;
}
-LogicalResult InlinerPass::initializeOptions(StringRef options) {
- if (failed(Pass::initializeOptions(options)))
+LogicalResult InlinerPass::initializeOptions(
+ StringRef options,
+ function_ref errorHandler) {
+ if (failed(Pass::initializeOptions(options, errorHandler)))
return failure();
// Initialize the pipeline builder for operations without the dedicated
diff --git a/mlir/test/Dialect/Transform/test-pass-application.mlir b/mlir/test/Dialect/Transform/test-pass-application.mlir
index 7cb5387b937d..460ac3947f5c 100644
--- a/mlir/test/Dialect/Transform/test-pass-application.mlir
+++ b/mlir/test/Dialect/Transform/test-pass-application.mlir
@@ -78,6 +78,7 @@ module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%arg1: !transform.any_op) {
%1 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op
// expected-error @below {{failed to add pass or pass pipeline to pipeline: canonicalize}}
+ // expected-error @below {{: no such option invalid-option}}
transform.apply_registered_pass "canonicalize" to %1 {options = "invalid-option=1"} : (!transform.any_op) -> !transform.any_op
transform.yield
}
--
GitLab
From 6d0174e70641b1ea172ffed07c43604ef15e28ae Mon Sep 17 00:00:00 2001
From: Stephen Neuendorffer
Date: Mon, 1 Apr 2024 17:04:29 -0700
Subject: [PATCH 025/442] [libc] allow libc-hdrgen to work on windows files
(#87292)
The code does some (overly simple?) checks on file syntax. These checks
assume unix line endings and fail on windows. This commit updates the
code to strip extra whitespace, making the checks more robust,
particularly in the presence of windows line endings.
Fixes #86023
---
libc/utils/HdrGen/Generator.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/libc/utils/HdrGen/Generator.cpp b/libc/utils/HdrGen/Generator.cpp
index 3bcf005adda7..d926d5d9ac3c 100644
--- a/libc/utils/HdrGen/Generator.cpp
+++ b/libc/utils/HdrGen/Generator.cpp
@@ -84,11 +84,19 @@ void Generator::generate(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) {
Line = Line.drop_front(CommandPrefixSize);
P = Line.split("(");
+ // It's possible that we have windows line endings, so strip off the extra
+ // CR.
+ P.second = P.second.trim();
if (P.second.empty() || P.second[P.second.size() - 1] != ')') {
SrcMgr.PrintMessage(llvm::SMLoc::getFromPointer(P.second.data()),
llvm::SourceMgr::DK_Error,
"Command argument list should begin with '(' "
"and end with ')'.");
+ SrcMgr.PrintMessage(llvm::SMLoc::getFromPointer(P.second.data()),
+ llvm::SourceMgr::DK_Error, P.second.data());
+ SrcMgr.PrintMessage(llvm::SMLoc::getFromPointer(P.second.data()),
+ llvm::SourceMgr::DK_Error,
+ std::to_string(P.second.size()));
std::exit(1);
}
llvm::StringRef CommandName = P.first;
--
GitLab
From dd5797505ebc2dbfdd58927c4f0a11a1256696eb Mon Sep 17 00:00:00 2001
From: Abhinav Gunjal
Date: Mon, 1 Apr 2024 17:36:09 -0700
Subject: [PATCH 026/442] lit_test : check if there is already a deps key in
kwargs (#87290)
This change checks if there is already a `deps` key in `kwargs` and
concatenate it to avoid multiple values for `deps` key argument.
background:
https://github.com/llvm/llvm-project/pull/87022 recently added explicit
`deps` to the lit_test. This is causing StableHLO bazel build failures
at
https://github.com/openxla/stablehlo/actions/runs/8511888283/job/23312383380?pr=2147
Tested: local build run is successful
---
utils/bazel/llvm-project-overlay/llvm/lit_test.bzl | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/utils/bazel/llvm-project-overlay/llvm/lit_test.bzl b/utils/bazel/llvm-project-overlay/llvm/lit_test.bzl
index f754a9fc7d5e..af7ae560768d 100644
--- a/utils/bazel/llvm-project-overlay/llvm/lit_test.bzl
+++ b/utils/bazel/llvm-project-overlay/llvm/lit_test.bzl
@@ -10,6 +10,7 @@ def lit_test(
srcs,
args = None,
data = None,
+ deps = None,
**kwargs):
"""Runs a single test file with LLVM's lit tool.
@@ -27,6 +28,7 @@ def lit_test(
args = args or []
data = data or []
+ deps = deps or []
native.py_test(
name = name,
@@ -35,7 +37,7 @@ def lit_test(
args = args + ["-v"] + ["$(execpath %s)" % src for src in srcs],
data = data + srcs,
legacy_create_init = False,
- deps = [Label("//llvm:lit")],
+ deps = deps + [Label("//llvm:lit")],
**kwargs
)
--
GitLab
From 9dbd364589883ae3343a291077804c564d4b3de5 Mon Sep 17 00:00:00 2001
From: Ben Shi <2283975856@qq.com>
Date: Tue, 2 Apr 2024 08:38:02 +0800
Subject: [PATCH 027/442] [AVR][NFC] Improve format of target description files
(#87212)
---
llvm/lib/Target/AVR/AVRInstrInfo.td | 320 +++++++---------------------
1 file changed, 75 insertions(+), 245 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td
index fe0d3b6c8189..38ebfab64c61 100644
--- a/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -343,13 +343,9 @@ def AVR_COND_PL : PatLeaf<(i8 7)>;
// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
// sub / add which can clobber SREG.
let Defs = [SP, SREG], Uses = [SP] in {
- def ADJCALLSTACKDOWN : Pseudo<(outs),
- (ins i16imm
- : $amt, i16imm
- : $amt2),
- "#ADJCALLSTACKDOWN", [(AVRcallseq_start timm
- : $amt, timm
- : $amt2)]>;
+ def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt, i16imm:$amt2),
+ "#ADJCALLSTACKDOWN",
+ [(AVRcallseq_start timm:$amt, timm:$amt2)]>;
// R31R30 is used to update SP. It is normally free because it is a
// call-clobbered register but it is necessary to set it as a def as the
@@ -357,13 +353,8 @@ let Defs = [SP, SREG], Uses = [SP] in {
// seems). hasSideEffects needs to be set to true so this instruction isn't
// considered dead.
let Defs = [R31R30], hasSideEffects = 1 in def ADJCALLSTACKUP
- : Pseudo<(outs),
- (ins i16imm
- : $amt1, i16imm
- : $amt2),
- "#ADJCALLSTACKUP", [(AVRcallseq_end timm
- : $amt1, timm
- : $amt2)]>;
+ : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
+ "#ADJCALLSTACKUP", [(AVRcallseq_end timm:$amt1, timm:$amt2)]>;
}
//===----------------------------------------------------------------------===//
@@ -372,19 +363,9 @@ let Defs = [SP, SREG], Uses = [SP] in {
let isCommutable = 1, Constraints = "$src = $rd", Defs = [SREG] in {
// ADD Rd, Rr
// Adds two 8-bit registers.
- def ADDRdRr
- : FRdRr<0b0000, 0b11,
- (outs GPR8
- : $rd),
- (ins GPR8
- : $src, GPR8
- : $rr),
- "add\t$rd, $rr",
- [(set i8
- : $rd, (add i8
- : $src, i8
- : $rr)),
- (implicit SREG)]>;
+ def ADDRdRr : FRdRr<0b0000, 0b11, (outs GPR8:$rd),(ins GPR8:$src, GPR8:$rr),
+ "add\t$rd, $rr",
+ [(set i8:$rd, (add i8:$src, i8:$rr)), (implicit SREG)]>;
// ADDW Rd+1:Rd, Rr+1:Rr
// Pseudo instruction to add four 8-bit registers as two 16-bit values.
@@ -392,34 +373,17 @@ let isCommutable = 1, Constraints = "$src = $rd", Defs = [SREG] in {
// Expands to:
// add Rd, Rr
// adc Rd+1, Rr+1
- def ADDWRdRr
- : Pseudo<(outs DREGS
- : $rd),
- (ins DREGS
- : $src, DREGS
- : $rr),
- "addw\t$rd, $rr",
- [(set i16
- : $rd, (add i16
- : $src, i16
- : $rr)),
- (implicit SREG)]>;
+ def ADDWRdRr : Pseudo<(outs DREGS:$rd), (ins DREGS:$src, DREGS:$rr),
+ "addw\t$rd, $rr",
+ [(set i16:$rd, (add i16:$src, i16:$rr)),
+ (implicit SREG)]>;
// ADC Rd, Rr
// Adds two 8-bit registers with carry.
- let Uses = [SREG] in def ADCRdRr
- : FRdRr<0b0001, 0b11,
- (outs GPR8
- : $rd),
- (ins GPR8
- : $src, GPR8
- : $rr),
- "adc\t$rd, $rr",
- [(set i8
- : $rd, (adde i8
- : $src, i8
- : $rr)),
- (implicit SREG)]>;
+ let Uses = [SREG] in
+ def ADCRdRr : FRdRr<0b0001, 0b11, (outs GPR8:$rd), (ins GPR8:$src, GPR8:$rr),
+ "adc\t$rd, $rr",
+ [(set i8:$rd, (adde i8:$src, i8:$rr)), (implicit SREG)]>;
// ADCW Rd+1:Rd, Rr+1:Rr
// Pseudo instruction to add four 8-bit registers as two 16-bit values with
@@ -428,56 +392,30 @@ let isCommutable = 1, Constraints = "$src = $rd", Defs = [SREG] in {
// Expands to:
// adc Rd, Rr
// adc Rd+1, Rr+1
- let Uses = [SREG] in def ADCWRdRr : Pseudo<(outs DREGS
- : $rd),
- (ins DREGS
- : $src, DREGS
- : $rr),
- "adcw\t$rd, $rr", [
- (set i16
- : $rd, (adde i16
- : $src, i16
- : $rr)),
- (implicit SREG)
- ]>;
+ let Uses = [SREG] in
+ def ADCWRdRr : Pseudo<(outs DREGS:$rd), (ins DREGS:$src, DREGS:$rr),
+ "adcw\t$rd, $rr",
+ [(set i16:$rd, (adde i16:$src, i16:$rr)),
+ (implicit SREG)]>;
// AIDW Rd, k
// Adds an immediate 6-bit value K to Rd, placing the result in Rd.
- def ADIWRdK
- : FWRdK<0b0,
- (outs IWREGS
- : $rd),
- (ins IWREGS
- : $src, imm_arith6
- : $k),
- "adiw\t$rd, $k",
- [(set i16
- : $rd, (add i16
- : $src, uimm6
- : $k)),
- (implicit SREG)]>,
- Requires<[HasADDSUBIW]>;
+ def ADIWRdK : FWRdK<0b0, (outs IWREGS:$rd), (ins IWREGS :$src, imm_arith6:$k),
+ "adiw\t$rd, $k",
+ [(set i16:$rd, (add i16:$src, uimm6:$k)),
+ (implicit SREG)]>,
+ Requires<[HasADDSUBIW]>;
}
//===----------------------------------------------------------------------===//
// Subtraction
//===----------------------------------------------------------------------===//
-let Constraints = "$src = $rd", Defs = [SREG] in {
+let Constraints = "$rs = $rd", Defs = [SREG] in {
// SUB Rd, Rr
// Subtracts the 8-bit value of Rr from Rd and places the value in Rd.
- def SUBRdRr
- : FRdRr<0b0001, 0b10,
- (outs GPR8
- : $rd),
- (ins GPR8
- : $src, GPR8
- : $rr),
- "sub\t$rd, $rr",
- [(set i8
- : $rd, (sub i8
- : $src, i8
- : $rr)),
- (implicit SREG)]>;
+ def SUBRdRr : FRdRr<0b0001, 0b10, (outs GPR8:$rd), (ins GPR8:$rs, GPR8:$rr),
+ "sub\t$rd, $rr",
+ [(set i8:$rd, (sub i8:$rs, i8:$rr)), (implicit SREG)]>;
// SUBW Rd+1:Rd, Rr+1:Rr
// Subtracts two 16-bit values and places the result into Rd.
@@ -485,129 +423,58 @@ let Constraints = "$src = $rd", Defs = [SREG] in {
// Expands to:
// sub Rd, Rr
// sbc Rd+1, Rr+1
- def SUBWRdRr
- : Pseudo<(outs DREGS
- : $rd),
- (ins DREGS
- : $src, DREGS
- : $rr),
- "subw\t$rd, $rr",
- [(set i16
- : $rd, (sub i16
- : $src, i16
- : $rr)),
- (implicit SREG)]>;
+ def SUBWRdRr : Pseudo<(outs DREGS:$rd), (ins DREGS:$rs, DREGS:$rr),
+ "subw\t$rd, $rr",
+ [(set i16:$rd, (sub i16:$rs, i16:$rr)),
+ (implicit SREG)]>;
- def SUBIRdK
- : FRdK<0b0101,
- (outs LD8
- : $rd),
- (ins LD8
- : $src, imm_ldi8
- : $k),
- "subi\t$rd, $k",
- [(set i8
- : $rd, (sub i8
- : $src, imm
- : $k)),
- (implicit SREG)]>;
+ def SUBIRdK : FRdK<0b0101, (outs LD8:$rd), (ins LD8:$rs, imm_ldi8:$k),
+ "subi\t$rd, $k",
+ [(set i8:$rd, (sub i8:$rs, imm:$k)), (implicit SREG)]>;
// SUBIW Rd+1:Rd, K+1:K
//
// Expands to:
// subi Rd, K
// sbci Rd+1, K+1
- def SUBIWRdK
- : Pseudo<(outs DLDREGS
- : $rd),
- (ins DLDREGS
- : $src, i16imm
- : $rr),
- "subiw\t$rd, $rr",
- [(set i16
- : $rd, (sub i16
- : $src, imm
- : $rr)),
- (implicit SREG)]>;
+ def SUBIWRdK : Pseudo<(outs DLDREGS:$rd), (ins DLDREGS:$rs, i16imm:$rr),
+ "subiw\t$rd, $rr",
+ [(set i16:$rd, (sub i16:$rs, imm:$rr)),
+ (implicit SREG)]>;
- def SBIWRdK
- : FWRdK<0b1,
- (outs IWREGS
- : $rd),
- (ins IWREGS
- : $src, imm_arith6
- : $k),
- "sbiw\t$rd, $k",
- [(set i16
- : $rd, (sub i16
- : $src, uimm6
- : $k)),
- (implicit SREG)]>,
- Requires<[HasADDSUBIW]>;
+ def SBIWRdK : FWRdK<0b1, (outs IWREGS:$rd), (ins IWREGS:$rs, imm_arith6:$k),
+ "sbiw\t$rd, $k",
+ [(set i16:$rd, (sub i16:$rs, uimm6:$k)),
+ (implicit SREG)]>,
+ Requires<[HasADDSUBIW]>;
// Subtract with carry operations which must read the carry flag in SREG.
let Uses = [SREG] in {
- def SBCRdRr
- : FRdRr<0b0000, 0b10,
- (outs GPR8
- : $rd),
- (ins GPR8
- : $src, GPR8
- : $rr),
- "sbc\t$rd, $rr",
- [(set i8
- : $rd, (sube i8
- : $src, i8
- : $rr)),
- (implicit SREG)]>;
+ def SBCRdRr : FRdRr<0b0000, 0b10, (outs GPR8:$rd), (ins GPR8:$rs, GPR8:$rr),
+ "sbc\t$rd, $rr",
+ [(set i8:$rd, (sube i8:$rs, i8:$rr)), (implicit SREG)]>;
// SBCW Rd+1:Rd, Rr+1:Rr
//
// Expands to:
// sbc Rd, Rr
// sbc Rd+1, Rr+1
- def SBCWRdRr : Pseudo<(outs DREGS
- : $rd),
- (ins DREGS
- : $src, DREGS
- : $rr),
- "sbcw\t$rd, $rr", [
- (set i16
- : $rd, (sube i16
- : $src, i16
- : $rr)),
- (implicit SREG)
- ]>;
+ def SBCWRdRr : Pseudo<(outs DREGS:$rd), (ins DREGS:$rs, DREGS:$rr),
+ "sbcw\t$rd, $rr",
+ [(set i16:$rd, (sube i16:$rs, i16:$rr)),
+ (implicit SREG)]>;
- def SBCIRdK
- : FRdK<0b0100,
- (outs LD8
- : $rd),
- (ins LD8
- : $src, imm_ldi8
- : $k),
- "sbci\t$rd, $k",
- [(set i8
- : $rd, (sube i8
- : $src, imm
- : $k)),
- (implicit SREG)]>;
+ def SBCIRdK : FRdK<0b0100, (outs LD8:$rd), (ins LD8:$rs, imm_ldi8:$k),
+ "sbci\t$rd, $k",
+ [(set i8:$rd, (sube i8:$rs, imm:$k)), (implicit SREG)]>;
// SBCIW Rd+1:Rd, K+1:K
// sbci Rd, K
// sbci Rd+1, K+1
- def SBCIWRdK : Pseudo<(outs DLDREGS
- : $rd),
- (ins DLDREGS
- : $src, i16imm
- : $rr),
- "sbciw\t$rd, $rr", [
- (set i16
- : $rd, (sube i16
- : $src, imm
- : $rr)),
- (implicit SREG)
- ]>;
+ def SBCIWRdK : Pseudo<(outs DLDREGS:$rd), (ins DLDREGS:$rs, i16imm:$rr),
+ "sbciw\t$rd, $rr",
+ [(set i16:$rd, (sube i16:$rs, imm:$rr)),
+ (implicit SREG)]>;
}
}
@@ -615,27 +482,13 @@ let Constraints = "$src = $rd", Defs = [SREG] in {
// Increment and Decrement
//===----------------------------------------------------------------------===//
let Constraints = "$src = $rd", Defs = [SREG] in {
- def INCRd
- : FRd<0b1001, 0b0100011,
- (outs GPR8
- : $rd),
- (ins GPR8
- : $src),
- "inc\t$rd", [(set i8
- : $rd, (add i8
- : $src, 1)),
- (implicit SREG)]>;
+ def INCRd : FRd<0b1001, 0b0100011, (outs GPR8:$rd), (ins GPR8:$src),
+ "inc\t$rd",
+ [(set i8:$rd, (add i8:$src, 1)), (implicit SREG)]>;
- def DECRd
- : FRd<0b1001, 0b0101010,
- (outs GPR8
- : $rd),
- (ins GPR8
- : $src),
- "dec\t$rd", [(set i8
- : $rd, (add i8
- : $src, -1)),
- (implicit SREG)]>;
+ def DECRd : FRd<0b1001, 0b0101010, (outs GPR8:$rd), (ins GPR8:$src),
+ "dec\t$rd",
+ [(set i8:$rd, (add i8:$src, -1)), (implicit SREG)]>;
}
//===----------------------------------------------------------------------===//
@@ -646,58 +499,35 @@ let isCommutable = 1, Defs = [R1, R0, SREG] in {
// MUL Rd, Rr
// Multiplies Rd by Rr and places the result into R1:R0.
let usesCustomInserter = 1 in {
- def MULRdRr : FRdRr<0b1001, 0b11, (outs),
- (ins GPR8
- : $rd, GPR8
- : $rr),
- "mul\t$rd, $rr",
- [/*(set R1, R0, (smullohi i8:$rd, i8:$rr))*/]>,
+ def MULRdRr : FRdRr<0b1001, 0b11, (outs), (ins GPR8:$rd, GPR8:$rr),
+ "mul\t$rd, $rr", []>,
Requires<[SupportsMultiplication]>;
- def MULSRdRr : FMUL2RdRr<0, (outs),
- (ins LD8
- : $rd, LD8
- : $rr),
+ def MULSRdRr : FMUL2RdRr<0, (outs), (ins LD8:$rd, LD8:$rr),
"muls\t$rd, $rr", []>,
Requires<[SupportsMultiplication]>;
}
- def MULSURdRr : FMUL2RdRr<1, (outs),
- (ins LD8lo
- : $rd, LD8lo
- : $rr),
+ def MULSURdRr : FMUL2RdRr<1, (outs), (ins LD8lo:$rd, LD8lo:$rr),
"mulsu\t$rd, $rr", []>,
Requires<[SupportsMultiplication]>;
- def FMUL : FFMULRdRr<0b01, (outs),
- (ins LD8lo
- : $rd, LD8lo
- : $rr),
+ def FMUL : FFMULRdRr<0b01, (outs), (ins LD8lo:$rd, LD8lo:$rr),
"fmul\t$rd, $rr", []>,
Requires<[SupportsMultiplication]>;
- def FMULS : FFMULRdRr<0b10, (outs),
- (ins LD8lo
- : $rd, LD8lo
- : $rr),
+ def FMULS : FFMULRdRr<0b10, (outs), (ins LD8lo:$rd, LD8lo:$rr),
"fmuls\t$rd, $rr", []>,
Requires<[SupportsMultiplication]>;
- def FMULSU : FFMULRdRr<0b11, (outs),
- (ins LD8lo
- : $rd, LD8lo
- : $rr),
+ def FMULSU : FFMULRdRr<0b11, (outs), (ins LD8lo:$rd, LD8lo:$rr),
"fmulsu\t$rd, $rr", []>,
Requires<[SupportsMultiplication]>;
}
let Defs =
- [R15, R14, R13, R12, R11, R10, R9, R8, R7, R6, R5, R4, R3, R2, R1,
- R0] in def DESK : FDES<(outs),
- (ins i8imm
- : $k),
- "des\t$k", []>,
- Requires<[HasDES]>;
+ [R15, R14, R13, R12, R11, R10, R9, R8, R7, R6, R5, R4, R3, R2, R1, R0] in
+def DESK : FDES<(outs), (ins i8imm:$k), "des\t$k", []>, Requires<[HasDES]>;
//===----------------------------------------------------------------------===//
// Logic
--
GitLab
From 372c275800140f35a697f12a2e83d94d5603eaf5 Mon Sep 17 00:00:00 2001
From: Vitaly Buka
Date: Mon, 1 Apr 2024 17:28:44 -0700
Subject: [PATCH 028/442] [dfsan][test] Disable the test with
internal_symbolizer
After #87191 we had to add
8b135a7d1f59a5a7adccb162abf92d751209afe7, which
makes symbolizer to calls a global constructor
with `realloc`.
---
compiler-rt/test/dfsan/mmap_at_init.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/compiler-rt/test/dfsan/mmap_at_init.c b/compiler-rt/test/dfsan/mmap_at_init.c
index a8d7535df4a6..9129dc7d3903 100644
--- a/compiler-rt/test/dfsan/mmap_at_init.c
+++ b/compiler-rt/test/dfsan/mmap_at_init.c
@@ -4,6 +4,9 @@
//
// Tests that calling mmap() during during dfsan initialization works.
+// `internal_symbolizer` can not use `realloc` on memory from the test `calloc`.
+// UNSUPPORTED: internal_symbolizer
+
#include
#include
#include
--
GitLab
From f33a6dcf959238e82f6ad45333e3547d8cfcfe38 Mon Sep 17 00:00:00 2001
From: Chen Zheng
Date: Tue, 2 Apr 2024 08:40:28 +0800
Subject: [PATCH 029/442] [PPC][NFC] add an option for GatherAllAliasesMaxDepth
(#87071)
GatherAllAliases is time consuming. Add an debug option on PPC to
control the complexity of the function. This is useful when debuging
compile time related issues.
---
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 7436b202fba0..43e4a34a9b34 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -137,6 +137,10 @@ static cl::opt PPCMinimumJumpTableEntries(
"ppc-min-jump-table-entries", cl::init(64), cl::Hidden,
cl::desc("Set minimum number of entries to use a jump table on PPC"));
+static cl::opt PPCGatherAllAliasesMaxDepth(
+ "ppc-gather-alias-max-depth", cl::init(18), cl::Hidden,
+ cl::desc("max depth when checking alias info in GatherAllAliases()"));
+
STATISTIC(NumTailCalls, "Number of tail calls");
STATISTIC(NumSiblingCalls, "Number of sibling calls");
STATISTIC(ShufflesHandledWithVPERM,
@@ -1512,6 +1516,8 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
// than the corresponding branch. This information is used in CGP to decide
// when to convert selects into branches.
PredictableSelectIsExpensive = Subtarget.isPredictableSelectIsExpensive();
+
+ GatherAllAliasesMaxDepth = PPCGatherAllAliasesMaxDepth;
}
// *********************************** NOTE ************************************
--
GitLab
From 84f24c2daffc40fc10b4ea2ae69016ebdabfc0ed Mon Sep 17 00:00:00 2001
From: Shih-Po Hung
Date: Tue, 2 Apr 2024 09:26:27 +0800
Subject: [PATCH 030/442] [RISCV][TTI] Scale the cost of intrinsic
umin/umax/smin/smax with LMUL (#87245)
Use the return type to measure the LMUL size for throughput/latency cost
---
.../Target/RISCV/RISCVTargetTransformInfo.cpp | 22 +++-
.../Analysis/CostModel/RISCV/int-min-max.ll | 120 +++++++++---------
2 files changed, 80 insertions(+), 62 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
index efcaa65605e0..ed4b0ca8c941 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
@@ -810,9 +810,27 @@ RISCVTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
case Intrinsic::smin:
case Intrinsic::smax: {
auto LT = getTypeLegalizationCost(RetTy);
- if ((ST->hasVInstructions() && LT.second.isVector()) ||
- (LT.second.isScalarInteger() && ST->hasStdExtZbb()))
+ if (LT.second.isScalarInteger() && ST->hasStdExtZbb())
return LT.first;
+
+ if (ST->hasVInstructions() && LT.second.isVector()) {
+ unsigned Op;
+ switch (ICA.getID()) {
+ case Intrinsic::umin:
+ Op = RISCV::VMINU_VV;
+ break;
+ case Intrinsic::umax:
+ Op = RISCV::VMAXU_VV;
+ break;
+ case Intrinsic::smin:
+ Op = RISCV::VMIN_VV;
+ break;
+ case Intrinsic::smax:
+ Op = RISCV::VMAX_VV;
+ break;
+ }
+ return LT.first * getRISCVInstructionCost(Op, LT.second, CostKind);
+ }
break;
}
case Intrinsic::sadd_sat:
diff --git a/llvm/test/Analysis/CostModel/RISCV/int-min-max.ll b/llvm/test/Analysis/CostModel/RISCV/int-min-max.ll
index ec669c986c15..79cf1c84ed49 100644
--- a/llvm/test/Analysis/CostModel/RISCV/int-min-max.ll
+++ b/llvm/test/Analysis/CostModel/RISCV/int-min-max.ll
@@ -12,36 +12,36 @@ define void @smax() {
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %7 = call @llvm.smax.nxv2i8( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %8 = call @llvm.smax.nxv4i8( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %9 = call @llvm.smax.nxv8i8( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %10 = call @llvm.smax.nxv16i8( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %10 = call @llvm.smax.nxv16i8( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %11 = call i16 @llvm.smax.i16(i16 undef, i16 undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %12 = call <2 x i16> @llvm.smax.v2i16(<2 x i16> undef, <2 x i16> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %13 = call <4 x i16> @llvm.smax.v4i16(<4 x i16> undef, <4 x i16> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %14 = call <8 x i16> @llvm.smax.v8i16(<8 x i16> undef, <8 x i16> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %15 = call <16 x i16> @llvm.smax.v16i16(<16 x i16> undef, <16 x i16> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %15 = call <16 x i16> @llvm.smax.v16i16(<16 x i16> undef, <16 x i16> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %16 = call @llvm.smax.nxv1i16( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %17 = call @llvm.smax.nxv2i16( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %18 = call @llvm.smax.nxv4i16( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %19 = call @llvm.smax.nxv8i16( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %20 = call @llvm.smax.nxv16i16( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %19 = call @llvm.smax.nxv8i16( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %20 = call @llvm.smax.nxv16i16( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %21 = call i32 @llvm.smax.i32(i32 undef, i32 undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %22 = call <2 x i32> @llvm.smax.v2i32(<2 x i32> undef, <2 x i32> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %23 = call <4 x i32> @llvm.smax.v4i32(<4 x i32> undef, <4 x i32> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %24 = call <8 x i32> @llvm.smax.v8i32(<8 x i32> undef, <8 x i32> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %25 = call <16 x i32> @llvm.smax.v16i32(<16 x i32> undef, <16 x i32> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %24 = call <8 x i32> @llvm.smax.v8i32(<8 x i32> undef, <8 x i32> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %25 = call <16 x i32> @llvm.smax.v16i32(<16 x i32> undef, <16 x i32> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %26 = call @llvm.smax.nxv1i32( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %27 = call @llvm.smax.nxv2i32( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %28 = call @llvm.smax.nxv4i32( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %29 = call @llvm.smax.nxv8i32( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %30 = call @llvm.smax.nxv16i32( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %28 = call @llvm.smax.nxv4i32( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %29 = call @llvm.smax.nxv8i32( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %30 = call @llvm.smax.nxv16i32( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %31 = call i64 @llvm.smax.i64(i64 undef, i64 undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %32 = call <2 x i64> @llvm.smax.v2i64(<2 x i64> undef, <2 x i64> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %33 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> undef, <4 x i64> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %34 = call <8 x i64> @llvm.smax.v8i64(<8 x i64> undef, <8 x i64> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %35 = call <16 x i64> @llvm.smax.v16i64(<16 x i64> undef, <16 x i64> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %33 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> undef, <4 x i64> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %34 = call <8 x i64> @llvm.smax.v8i64(<8 x i64> undef, <8 x i64> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %35 = call <16 x i64> @llvm.smax.v16i64(<16 x i64> undef, <16 x i64> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %36 = call @llvm.smax.nxv1i64( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %37 = call @llvm.smax.nxv2i64( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %38 = call @llvm.smax.nxv4i64( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %39 = call @llvm.smax.nxv8i64( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %37 = call @llvm.smax.nxv2i64( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %38 = call @llvm.smax.nxv4i64( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %39 = call @llvm.smax.nxv8i64( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void
;
call i8 @llvm.smax.i8(i8 undef, i8 undef)
@@ -97,36 +97,36 @@ define void @smin() {
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %7 = call @llvm.smin.nxv2i8( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %8 = call @llvm.smin.nxv4i8( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %9 = call @llvm.smin.nxv8i8( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %10 = call @llvm.smin.nxv16i8( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %10 = call @llvm.smin.nxv16i8( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %11 = call i16 @llvm.smin.i16(i16 undef, i16 undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %12 = call <2 x i16> @llvm.smin.v2i16(<2 x i16> undef, <2 x i16> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %13 = call <4 x i16> @llvm.smin.v4i16(<4 x i16> undef, <4 x i16> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %14 = call <8 x i16> @llvm.smin.v8i16(<8 x i16> undef, <8 x i16> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %15 = call <16 x i16> @llvm.smin.v16i16(<16 x i16> undef, <16 x i16> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %15 = call <16 x i16> @llvm.smin.v16i16(<16 x i16> undef, <16 x i16> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %16 = call @llvm.smin.nxv1i16( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %17 = call @llvm.smin.nxv2i16( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %18 = call @llvm.smin.nxv4i16( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %19 = call @llvm.smin.nxv8i16( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %20 = call @llvm.smin.nxv16i16( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %19 = call @llvm.smin.nxv8i16( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %20 = call @llvm.smin.nxv16i16( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %21 = call i32 @llvm.smin.i32(i32 undef, i32 undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %22 = call <2 x i32> @llvm.smin.v2i32(<2 x i32> undef, <2 x i32> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %23 = call <4 x i32> @llvm.smin.v4i32(<4 x i32> undef, <4 x i32> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %24 = call <8 x i32> @llvm.smin.v8i32(<8 x i32> undef, <8 x i32> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %25 = call <16 x i32> @llvm.smin.v16i32(<16 x i32> undef, <16 x i32> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %24 = call <8 x i32> @llvm.smin.v8i32(<8 x i32> undef, <8 x i32> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %25 = call <16 x i32> @llvm.smin.v16i32(<16 x i32> undef, <16 x i32> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %26 = call @llvm.smin.nxv1i32( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %27 = call @llvm.smin.nxv2i32( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %28 = call @llvm.smin.nxv4i32( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %29 = call @llvm.smin.nxv8i32( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %30 = call @llvm.smin.nxv16i32( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %28 = call @llvm.smin.nxv4i32( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %29 = call @llvm.smin.nxv8i32( undef, undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %30 = call @llvm.smin.nxv16i32( undef, undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %31 = call i64 @llvm.smin.i64(i64 undef, i64 undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %32 = call <2 x i64> @llvm.smin.v2i64(<2 x i64> undef, <2 x i64> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %33 = call <4 x i64> @llvm.smin.v4i64(<4 x i64> undef, <4 x i64> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %34 = call <8 x i64> @llvm.smin.v8i64(<8 x i64> undef, <8 x i64> undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %35 = call <16 x i64> @llvm.smin.v16i64(<16 x i64> undef, <16 x i64> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %33 = call <4 x i64> @llvm.smin.v4i64(<4 x i64> undef, <4 x i64> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %34 = call <8 x i64> @llvm.smin.v8i64(<8 x i64> undef, <8 x i64> undef)
+; CHECK-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %35 = call <16 x i64> @llvm.smin.v16i64(<16 x i64> undef, <16 x i64> undef)
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %36 = call @llvm.smin.nxv1i64( undef, undef)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %37 = call @llvm.smin.nxv2i64( undef,