Skip to content

Recommit changes to global checks #71171

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 13, 2023
Merged

Conversation

hnrklssn
Copy link
Member

@hnrklssn hnrklssn commented Nov 3, 2023

Recommits the changes from https://reviews.llvm.org/D148216.
Explicitly named globals are now matched literally, instead of emitting a capture group for the name. This resolves #70047.
Metadata and annotations, on the other hand, are captured and matched against by default, since their identifiers are not stable.

The reasons for revert (#63746) have been fixed:
The first issue, that of duplicated checkers, has already been resolved in #70050.
This PR resolves the second issue listed in #63746, regarding the order of named and unnamed globals. This is fixed by recording the index of substrings containing global values, and sorting the checks according to that index before emitting them. This results in global value checks being emitted in the order they were seen instead of being grouped separately.

UTC version 3 already exists, bump the reintroduced changes to version 4.
Since the matcher for named globals was extracted into a separate match
instance (GLOBNAMED) UTC scripts would emit unnamed globals first,
followed by named globals. LLVM IR allows them to be interspersed in any
order, leading to CHECK lines being incorrectly ordered.

This fixes that by recording each check-line's index in the input file,
allowing them to be sorted properly after being collected. A new
attribute is added to NamelessValue (interlaced_with_previous), which
is set to True for GLOBNAMED, to indicate that it should be emitted
together with GLOB check-lines.
@hnrklssn hnrklssn requested review from nikic and jdoerfert November 3, 2023 11:03
@llvmbot llvmbot added clang Clang issues not falling into any other category testing-tools labels Nov 3, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 3, 2023

@llvm/pr-subscribers-testing-tools

@llvm/pr-subscribers-clang

Author: Henrik G. Olsson (hnrklssn)

Changes

Recommits the changes from https://reviews.llvm.org/D148216.
Explicitly named globals are now matched literally, instead of emitting a capture group for the name. This resolves #70047.
Metadata and annotations, on the other hand, are captured and matched against by default, since their identifiers are not stable.

The reasons for revert (#63746) have been fixed:
The first issue, that of duplicated checkers, has already been resolved in #70050.
This PR resolves the second issue listed in #63746, regarding the order of named and unnamed globals. This is fixed by recording the index of substrings containing global values, and sorting the checks according to that index before emitting them. This results in global value checks being emitted in the order they were seen instead of being grouped separately.


Patch is 97.06 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/71171.diff

21 Files Affected:

  • (added) clang/test/utils/update_cc_test_checks/Inputs/annotations.c (+6)
  • (added) clang/test/utils/update_cc_test_checks/Inputs/annotations.c.expected (+21)
  • (added) clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.all.expected (+258)
  • (modified) clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected (+6-1)
  • (added) clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.all.expected (+129)
  • (modified) clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected (+6-1)
  • (added) clang/test/utils/update_cc_test_checks/annotations.test (+4)
  • (modified) clang/test/utils/update_cc_test_checks/check-globals.test (+7-7)
  • (modified) clang/test/utils/update_cc_test_checks/generated-funcs.test (+14-2)
  • (modified) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.globals.expected (+1-1)
  • (modified) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.globals.expected (+1-1)
  • (modified) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs_prefix_reuse.ll.generated.globals.expected (+1-1)
  • (modified) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs_prefix_reuse.ll.nogenerated.globals.expected (+1-1)
  • (modified) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/global_regex.ll.expected (+1-1)
  • (modified) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.globals.expected (+58-58)
  • (added) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.noglobals.expected (+244)
  • (added) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.transitiveglobals.expected (+305)
  • (modified) llvm/test/tools/UpdateTestChecks/update_test_checks/various_ir_values.test (+6)
  • (modified) llvm/utils/UpdateTestChecks/common.py (+181-19)
  • (modified) llvm/utils/update_cc_test_checks.py (+13-7)
  • (modified) llvm/utils/update_test_checks.py (+9-3)
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/annotations.c b/clang/test/utils/update_cc_test_checks/Inputs/annotations.c
new file mode 100644
index 000000000000000..f09b0f788e9b128
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/Inputs/annotations.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s
+
+int foo() {
+    int x = x + 1;
+    return x;
+}
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/annotations.c.expected b/clang/test/utils/update_cc_test_checks/Inputs/annotations.c.expected
new file mode 100644
index 000000000000000..1eb82f6eb5ddccc
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/Inputs/annotations.c.expected
@@ -0,0 +1,21 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s
+
+// CHECK-LABEL: define dso_local i32 @foo(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 0, ptr [[X]], align 4, !annotation [[META2:![0-9]+]]
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X]], align 4
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP0]], 1
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[X]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[X]], align 4
+// CHECK-NEXT:    ret i32 [[TMP1]]
+//
+int foo() {
+    int x = x + 1;
+    return x;
+}
+//.
+// CHECK: [[META2]] = !{!"auto-init"}
+//.
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.all.expected b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.all.expected
new file mode 100644
index 000000000000000..b3945741ad49577
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.all.expected
@@ -0,0 +1,258 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs
+// Check that the CHECK lines are generated for clang-generated functions
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck --check-prefix=OMP %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck --check-prefix=NOOMP %s
+
+const int size = 1024 * 1024 * 32;
+
+double A[size];
+
+void foo(void);
+
+int main(void) {
+  int i = 0;
+
+#pragma omp parallel for
+  for (i = 0; i < size; ++i) {
+    A[i] = 0.0;
+  }
+
+  foo();
+
+  return 0;
+}
+
+void foo(void) {
+  int i = 0;
+
+#pragma omp parallel for
+  for (i = 0; i < size; ++i) {
+    A[i] = 1.0;
+  }
+}
+//.
+// OMP: @A = global [33554432 x double] zeroinitializer, align 16
+// OMP: @size = constant i32 33554432, align 4
+// OMP: @[[GLOB0:[0-9]+]] = private unnamed_addr constant [23 x i8] c"
+// OMP: @[[GLOB1:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 514, i32 0, i32 22, ptr @[[GLOB0]] }, align 8
+// OMP: @[[GLOB2:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @[[GLOB0]] }, align 8
+//.
+// NOOMP: @size = constant i32 33554432, align 4
+// NOOMP: @A = global [33554432 x double] zeroinitializer, align 16
+//.
+// OMP-LABEL: @main(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+// OMP-NEXT:    store i32 0, ptr [[I]], align 4
+// OMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @main.omp_outlined)
+// OMP-NEXT:    call void @foo()
+// OMP-NEXT:    ret i32 0
+//
+//
+// OMP-LABEL: @main.omp_outlined(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
+// OMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
+// OMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT:    store ptr [[DOTGLOBAL_TID_:%.*]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT:    store ptr [[DOTBOUND_TID_:%.*]], ptr [[DOTBOUND_TID__ADDR]], align 8
+// OMP-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// OMP-NEXT:    store i32 33554431, ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// OMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// OMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
+// OMP-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// OMP-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431
+// OMP-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// OMP:       cond.true:
+// OMP-NEXT:    br label [[COND_END:%.*]]
+// OMP:       cond.false:
+// OMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    br label [[COND_END]]
+// OMP:       cond.end:
+// OMP-NEXT:    [[COND:%.*]] = phi i32 [ 33554431, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
+// OMP-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// OMP-NEXT:    store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// OMP:       omp.inner.for.cond:
+// OMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
+// OMP-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// OMP:       omp.inner.for.body:
+// OMP-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
+// OMP-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// OMP-NEXT:    store i32 [[ADD]], ptr [[I]], align 4
+// OMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[I]], align 4
+// OMP-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP8]] to i64
+// OMP-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], ptr @A, i64 0, i64 [[IDXPROM]]
+// OMP-NEXT:    store double 0.000000e+00, ptr [[ARRAYIDX]], align 8
+// OMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// OMP:       omp.body.continue:
+// OMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// OMP:       omp.inner.for.inc:
+// OMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1
+// OMP-NEXT:    store i32 [[ADD2]], ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// OMP:       omp.inner.for.end:
+// OMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// OMP:       omp.loop.exit:
+// OMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]])
+// OMP-NEXT:    ret void
+//
+//
+// OMP-LABEL: @foo(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT:    store i32 0, ptr [[I]], align 4
+// OMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo.omp_outlined)
+// OMP-NEXT:    ret void
+//
+//
+// OMP-LABEL: @foo.omp_outlined(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
+// OMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
+// OMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT:    store ptr [[DOTGLOBAL_TID_:%.*]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT:    store ptr [[DOTBOUND_TID_:%.*]], ptr [[DOTBOUND_TID__ADDR]], align 8
+// OMP-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// OMP-NEXT:    store i32 33554431, ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// OMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// OMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
+// OMP-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// OMP-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431
+// OMP-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// OMP:       cond.true:
+// OMP-NEXT:    br label [[COND_END:%.*]]
+// OMP:       cond.false:
+// OMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    br label [[COND_END]]
+// OMP:       cond.end:
+// OMP-NEXT:    [[COND:%.*]] = phi i32 [ 33554431, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
+// OMP-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// OMP-NEXT:    store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// OMP:       omp.inner.for.cond:
+// OMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// OMP-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
+// OMP-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// OMP:       omp.inner.for.body:
+// OMP-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
+// OMP-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// OMP-NEXT:    store i32 [[ADD]], ptr [[I]], align 4
+// OMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[I]], align 4
+// OMP-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP8]] to i64
+// OMP-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], ptr @A, i64 0, i64 [[IDXPROM]]
+// OMP-NEXT:    store double 1.000000e+00, ptr [[ARRAYIDX]], align 8
+// OMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// OMP:       omp.body.continue:
+// OMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// OMP:       omp.inner.for.inc:
+// OMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1
+// OMP-NEXT:    store i32 [[ADD2]], ptr [[DOTOMP_IV]], align 4
+// OMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// OMP:       omp.inner.for.end:
+// OMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// OMP:       omp.loop.exit:
+// OMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]])
+// OMP-NEXT:    ret void
+//
+//
+// NOOMP-LABEL: @main(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+// NOOMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NOOMP-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+// NOOMP-NEXT:    store i32 0, ptr [[I]], align 4
+// NOOMP-NEXT:    store i32 0, ptr [[I]], align 4
+// NOOMP-NEXT:    br label [[FOR_COND:%.*]]
+// NOOMP:       for.cond:
+// NOOMP-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4
+// NOOMP-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 33554432
+// NOOMP-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// NOOMP:       for.body:
+// NOOMP-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I]], align 4
+// NOOMP-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64
+// NOOMP-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], ptr @A, i64 0, i64 [[IDXPROM]]
+// NOOMP-NEXT:    store double 0.000000e+00, ptr [[ARRAYIDX]], align 8
+// NOOMP-NEXT:    br label [[FOR_INC:%.*]]
+// NOOMP:       for.inc:
+// NOOMP-NEXT:    [[TMP2:%.*]] = load i32, ptr [[I]], align 4
+// NOOMP-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP2]], 1
+// NOOMP-NEXT:    store i32 [[INC]], ptr [[I]], align 4
+// NOOMP-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
+// NOOMP:       for.end:
+// NOOMP-NEXT:    call void @foo()
+// NOOMP-NEXT:    ret i32 0
+//
+//
+// NOOMP-LABEL: @foo(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NOOMP-NEXT:    store i32 0, ptr [[I]], align 4
+// NOOMP-NEXT:    store i32 0, ptr [[I]], align 4
+// NOOMP-NEXT:    br label [[FOR_COND:%.*]]
+// NOOMP:       for.cond:
+// NOOMP-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4
+// NOOMP-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 33554432
+// NOOMP-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// NOOMP:       for.body:
+// NOOMP-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I]], align 4
+// NOOMP-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64
+// NOOMP-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], ptr @A, i64 0, i64 [[IDXPROM]]
+// NOOMP-NEXT:    store double 1.000000e+00, ptr [[ARRAYIDX]], align 8
+// NOOMP-NEXT:    br label [[FOR_INC:%.*]]
+// NOOMP:       for.inc:
+// NOOMP-NEXT:    [[TMP2:%.*]] = load i32, ptr [[I]], align 4
+// NOOMP-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP2]], 1
+// NOOMP-NEXT:    store i32 [[INC]], ptr [[I]], align 4
+// NOOMP-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
+// NOOMP:       for.end:
+// NOOMP-NEXT:    ret void
+//
+//.
+// OMP: attributes #[[ATTR0:[0-9]+]] = { noinline nounwind optnone "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// OMP: attributes #[[ATTR1:[0-9]+]] = { noinline norecurse nounwind optnone "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// OMP: attributes #[[ATTR2:[0-9]+]] = { nounwind }
+//.
+// NOOMP: attributes #[[ATTR0:[0-9]+]] = { noinline nounwind optnone "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+//.
+// OMP: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+// OMP: [[META1:![0-9]+]] = !{i32 7, !"openmp", i32 51}
+// OMP: [[META2:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
+// OMP: [[META3:![0-9]+]] = !{[[META4:![0-9]+]]}
+// OMP: [[META4]] = !{i64 2, i64 -1, i64 -1, i1 true}
+//.
+// NOOMP: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+// NOOMP: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
+// NOOMP: [[LOOP2]] = distinct !{[[LOOP2]], [[META3:![0-9]+]]}
+// NOOMP: [[META3]] = !{!"llvm.loop.mustprogress"}
+// NOOMP: [[LOOP4]] = distinct !{[[LOOP4]], [[META3]]}
+//.
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
index 2479cb6e6943265..896d4ede3c053ba 100644
--- a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
+++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
@@ -1,4 +1,4 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals smart --include-generated-funcs
 // Check that the CHECK lines are generated for clang-generated functions
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck --check-prefix=OMP %s
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck --check-prefix=NOOMP %s
@@ -227,3 +227,8 @@ void foo(void) {
 // NOOMP:       for.end:
 // NOOMP-NEXT:    ret void
 //
+//.
+// NOOMP: [[LOOP2]] = distinct !{[[LOOP2]], [[META3:![0-9]+]]}
+// NOOMP: [[META3]] = !{!"llvm.loop.mustprogress"}
+// NOOMP: [[LOOP4]] = distinct !{[[LOOP4]], [[META3]]}
+//.
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.all.expected b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.all.expected
new file mode 100644
index 000000000000000..8eda594112e3fbf
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.all.expected
@@ -0,0 +1,129 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals
+// Check that the CHECK lines are generated for clang-generated functions
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck --check-prefix=OMP %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck --check-prefix=NOOMP %s
+
+const int size = 1024 * 1024 * 32;
+
+double A[size];
+
+void foo(void);
+
+//.
+// OMP: @A = global [33554432 x double] zeroinitializer, align 16
+// OMP: @size = constant i32 33554432, align 4
+// OMP: @[[GLOB0:[0-9]+]] = private unnamed_addr constant [23 x i8] c"
+// OMP: @[[GLOB1:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 514, i32 0, i32 22, ptr @[[GLOB0]] }, align 8
+// OMP: @[[GLOB2:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @[[GLOB0]] }, align 8
+//.
+// NOOMP: @size = constant i32 33554432, align 4
+// NOOMP: @A = global [33554432 x double] zeroinitializer, align 16
+//.
+// OMP-LABEL: @main(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+// OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+// OMP-NEXT:    store i32 0, ptr [[I]], align 4
+// OMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @main.omp_outlined)
+// OMP-NEXT:    call void @foo()
+// OMP-NEXT:    ret i32 0
+//
+// NOOMP-LABEL: @main(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+// NOOMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NOOMP-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+// NOOMP-NEXT:    store i32 0, ptr [[I]], align 4
+// NOOMP-NEXT:    store i32 0, ptr [[I]], align 4
+// NOOMP-NEXT:    br label [[FOR_COND:%.*]]
+// NOOMP:       for.cond:
+// NOOMP-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4
+// NOOMP-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 33554432
+// NOOMP-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// NOOMP:       for.body:
+// NOOMP-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I]], align 4
+// NOOMP-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64
+// NOOMP-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], ptr @A, i64 0, i64 [[IDXPROM]]
+// NOOMP-NEXT:    store double 0.000000e+00, ptr [[ARRAYIDX]], align 8
+// NOOMP-NEXT:    br label [[FOR_INC:%.*]]
+// NOOMP:       for.inc:
+// NOOMP-NEXT:    [[TMP2:%.*]] = load i32, ptr [[I]], align 4
+// NOOMP-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP2]], 1
+// NOOMP-NEXT:    store i32 [[INC]], ptr [[I]], align 4
+// NOOMP-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
+// NOOMP:       for.end:
+// NOOMP-NEXT:    call void @foo()
+// NOOMP-NEXT:    ret i32 0
+//
+int main(void) {
+  int i = 0;
+
+#pragma omp parallel for
+  for (i = 0; i < size; ++i) {
+    A[i] = 0.0;
+  }
+
+  foo();
+
+  return 0;
+}
+
+// OMP-LABEL: @foo(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT:    store i32 0, ptr [[I]], align 4
+// OMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo.omp_outlined)
+// OMP-NEXT:    ret void
+//
+// NOOMP-LABEL: @foo(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NOOMP-NEXT:    store i32 0, ptr [[I]], align 4
+// NOOMP-NEXT:    store i32 0, ptr [[I]], align 4
+// NOOMP-NEXT:    br label [[FOR_COND:%.*]]
+// NOOMP:       for.cond:
+// NOOMP-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4
+...
[truncated]

Copy link

github-actions bot commented Nov 3, 2023

⚠️ Python code formatter, darker found issues in your code. ⚠️

You can test this locally with the following command:
darker --check --diff -r 01689175251f2624fb9d077666657aa21e3f7850..9aac63be1f0d313830721472073426984e73e8a8 llvm/utils/UpdateTestChecks/common.py llvm/utils/update_cc_test_checks.py llvm/utils/update_test_checks.py
View the diff from darker here.
--- update_cc_test_checks.py	2023-11-03 10:35:29.000000 +0000
+++ update_cc_test_checks.py	2023-11-03 15:56:11.288194 +0000
@@ -437,11 +437,11 @@
                         func,
                         global_vars_seen_dict,
                         is_filtered=builder.is_filtered(),
                     )
 
-            if ti.args.check_globals != 'none':
+            if ti.args.check_globals != "none":
                 generated_prefixes.extend(
                     common.add_global_checks(
                         builder.global_var_dict(),
                         "//",
                         run_list,
@@ -495,11 +495,11 @@
                                 # Remove the comment line since we will generate a new  comment
                                 # line as part of common.add_ir_checks()
                                 output_lines.pop()
                                 last_line = output_lines[-1].strip()
                             if (
-                                ti.args.check_globals != 'none'
+                                ti.args.check_globals != "none"
                                 and not has_checked_pre_function_globals
                             ):
                                 generated_prefixes.extend(
                                     common.add_global_checks(
                                         builder.global_var_dict(),
@@ -534,11 +534,11 @@
                                 include_line = False
 
                 if include_line:
                     output_lines.append(line.rstrip("\n"))
 
-        if ti.args.check_globals != 'none':
+        if ti.args.check_globals != "none":
             generated_prefixes.extend(
                 common.add_global_checks(
                     builder.global_var_dict(),
                     "//",
                     run_list,
--- update_test_checks.py	2023-11-03 10:35:29.000000 +0000
+++ update_test_checks.py	2023-11-03 15:56:11.446420 +0000
@@ -196,11 +196,11 @@
             # be sure the input function order is maintained.  Therefore, first spit
             # out all the source lines.
             common.dump_input_lines(output_lines, ti, prefix_set, ";")
 
             args = ti.args
-            if args.check_globals != 'none':
+            if args.check_globals != "none":
                 generated_prefixes.extend(
                     common.add_global_checks(
                         builder.global_var_dict(),
                         ";",
                         prefix_list,
@@ -304,11 +304,11 @@
                 if args.function is not None and func_name != args.function:
                     # When filtering on a specific function, skip all others.
                     continue
                 is_in_function = is_in_function_start = True
 
-        if args.check_globals != 'none':
+        if args.check_globals != "none":
             generated_prefixes.extend(
                 common.add_global_checks(
                     builder.global_var_dict(),
                     ";",
                     prefix_list,

Copy link
Member

@jdoerfert jdoerfert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if the issues with the original commit are resolved, this is good to go.
Did you verify we can properly auto-generate files, e.g., in llvm/test/Transforms/Attributor and clang/test/OpenMP?

@hnrklssn
Copy link
Member Author

hnrklssn commented Nov 3, 2023

I think if the issues with the original commit are resolved, this is good to go.

Did you verify we can properly auto-generate files, e.g., in llvm/test/Transforms/Attributor and clang/test/OpenMP?

Ah no I did not, I'll do that on Monday.

@jdoerfert
Copy link
Member

I think if the issues with the original commit are resolved, this is good to go.
Did you verify we can properly auto-generate files, e.g., in llvm/test/Transforms/Attributor and clang/test/OpenMP?

Ah no I did not, I'll do that on Monday.

I'd run ./llvm/utils/update_any_test_checks.py once and see if the tests pass afterwards.
Then do it again to ensure the nasty ordering and duplication issues are gone for good.

@hnrklssn
Copy link
Member Author

I'd run ./llvm/utils/update_any_test_checks.py once and see if the tests pass afterwards.
Then do it again to ensure the nasty ordering and duplication issues are gone for good.

All tests that fail after running update_any_test_checks.py also fail when running it without this patch, so I don't see any regressions there. Running it a second time doesn't result in any changes.

@hnrklssn hnrklssn merged commit e6eda66 into llvm:main Nov 13, 2023
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
Recommits the changes from https://reviews.llvm.org/D148216.
Explicitly named globals are now matched literally, instead of emitting
a capture group for the name. This resolves llvm#70047.
Metadata and annotations, on the other hand, are captured and matched
against by default, since their identifiers are not stable.

The reasons for revert (llvm#63746) have been fixed:
The first issue, that of duplicated checkers, has already been resolved
in llvm#70050.
This PR resolves the second issue listed in llvm#63746, regarding the order
of named and unnamed globals. This is fixed by recording the index of
substrings containing global values, and sorting the checks according to
that index before emitting them. This results in global value checks
being emitted in the order they were seen instead of being grouped
separately.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category testing-tools
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[UTC] Match the names of named globals
3 participants