[clang] cd1bd6e - [Utils] Check for more global information in update_test_checks

Johannes Doerfert via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 11 21:31:22 PST 2021


Author: Johannes Doerfert
Date: 2021-03-11T23:31:16-06:00
New Revision: cd1bd6e5870044f3e35da3f713782563e0014c5d

URL: https://github.com/llvm/llvm-project/commit/cd1bd6e5870044f3e35da3f713782563e0014c5d
DIFF: https://github.com/llvm/llvm-project/commit/cd1bd6e5870044f3e35da3f713782563e0014c5d.diff

LOG: [Utils] Check for more global information in update_test_checks

This allows to check for various globals (metadata/attributes/...) and
also resolves problems with globals (metadata/attributes/...) being
reused across different prefixes.

Reviewed By: sstefan1

Differential Revision: https://reviews.llvm.org/D94741

Added: 
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.globals.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.globals.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.globals.expected

Modified: 
    clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
    clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
    clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
    clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.funcattrs.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.plain.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.plain.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/generated_funcs.test
    llvm/test/tools/UpdateTestChecks/update_test_checks/various_ir_values.test
    llvm/utils/UpdateTestChecks/common.py
    llvm/utils/update_test_checks.py

Removed: 
    


################################################################################
diff  --git a/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected b/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
index 4f8f6003bfb4..b9a8d5f55dc9 100644
--- a/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
+++ b/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
@@ -44,7 +44,7 @@ Foo::Foo(int x) : x(x) {}
 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %class.Foo*, align 8
 // CHECK-NEXT:    store %class.Foo* [[THIS:%.*]], %class.Foo** [[THIS_ADDR]], align 8
 // CHECK-NEXT:    [[THIS1:%.*]] = load %class.Foo*, %class.Foo** [[THIS_ADDR]], align 8
-// CHECK-NEXT:    call void @_ZN3FooD2Ev(%class.Foo* nonnull dereferenceable(4) [[THIS1]]) [[ATTR3:#.*]]
+// CHECK-NEXT:    call void @_ZN3FooD2Ev(%class.Foo* nonnull dereferenceable(4) [[THIS1]]) #[[ATTR3:[0-9]+]]
 // CHECK-NEXT:    ret void
 //
 Foo::~Foo() {}
@@ -70,7 +70,7 @@ int Foo::function_defined_out_of_line(int arg) const { return x - arg; }
 // CHECK-NEXT:    call void @_ZN3FooC1Ei(%class.Foo* nonnull dereferenceable(4) [[F]], i32 1)
 // CHECK-NEXT:    [[CALL:%.*]] = call i32 @_ZNK3Foo23function_defined_inlineEi(%class.Foo* nonnull dereferenceable(4) [[F]], i32 2)
 // CHECK-NEXT:    [[CALL1:%.*]] = call i32 @_ZNK3Foo28function_defined_out_of_lineEi(%class.Foo* nonnull dereferenceable(4) [[F]], i32 3)
-// CHECK-NEXT:    call void @_ZN3FooD1Ev(%class.Foo* nonnull dereferenceable(4) [[F]]) [[ATTR3]]
+// CHECK-NEXT:    call void @_ZN3FooD1Ev(%class.Foo* nonnull dereferenceable(4) [[F]]) #[[ATTR3]]
 // CHECK-NEXT:    ret i32 0
 //
 int main() {

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 cbdfff47675c..96868dd7bab1 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
@@ -34,7 +34,7 @@ void foo(void) {
 // OMP-NEXT:  entry:
 // OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
 // OMP-NEXT:    store i32 0, i32* [[I]], align 4
-// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB2:@.*]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
 // OMP-NEXT:    ret void
 //
 //
@@ -57,7 +57,7 @@ void foo(void) {
 // OMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
 // OMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
 // OMP-NEXT:    [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
-// OMP-NEXT:    call void @__kmpc_for_static_init_4(%struct.ident_t* [[GLOB1:@.*]], i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// OMP-NEXT:    call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
 // OMP-NEXT:    [[TMP2:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
 // OMP-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431
 // OMP-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
@@ -97,7 +97,7 @@ void foo(void) {
 // OMP:       omp.inner.for.end:
 // OMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
 // OMP:       omp.loop.exit:
-// OMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* [[GLOB1]], i32 [[TMP1]])
+// OMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]])
 // OMP-NEXT:    ret void
 //
 //
@@ -107,7 +107,7 @@ void foo(void) {
 // OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
 // OMP-NEXT:    store i32 0, i32* [[RETVAL]], align 4
 // OMP-NEXT:    store i32 0, i32* [[I]], align 4
-// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB2]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB2]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
 // OMP-NEXT:    call void @foo()
 // OMP-NEXT:    ret i32 0
 //
@@ -131,7 +131,7 @@ void foo(void) {
 // OMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
 // OMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
 // OMP-NEXT:    [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
-// OMP-NEXT:    call void @__kmpc_for_static_init_4(%struct.ident_t* [[GLOB1]], i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// OMP-NEXT:    call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
 // OMP-NEXT:    [[TMP2:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
 // OMP-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431
 // OMP-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
@@ -171,7 +171,7 @@ void foo(void) {
 // OMP:       omp.inner.for.end:
 // OMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
 // OMP:       omp.loop.exit:
-// OMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* [[GLOB1]], i32 [[TMP1]])
+// OMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]])
 // OMP-NEXT:    ret void
 //
 //
@@ -197,7 +197,7 @@ void foo(void) {
 // NOOMP-NEXT:    [[TMP2:%.*]] = load i32, i32* [[I]], align 4
 // NOOMP-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP2]], 1
 // NOOMP-NEXT:    store i32 [[INC]], i32* [[I]], align 4
-// NOOMP-NEXT:    br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
+// NOOMP-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
 // NOOMP:       for.end:
 // NOOMP-NEXT:    call void @foo()
 // NOOMP-NEXT:    ret i32 0
@@ -223,7 +223,7 @@ void foo(void) {
 // NOOMP-NEXT:    [[TMP2:%.*]] = load i32, i32* [[I]], align 4
 // NOOMP-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP2]], 1
 // NOOMP-NEXT:    store i32 [[INC]], i32* [[I]], align 4
-// NOOMP-NEXT:    br label [[FOR_COND]], [[LOOP4:!llvm.loop !.*]]
+// NOOMP-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
 // NOOMP:       for.end:
 // NOOMP-NEXT:    ret void
 //

diff  --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
index 7bb40144b0b1..6685e56c7422 100644
--- a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
+++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
@@ -15,7 +15,7 @@ void foo(void);
 // OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
 // OMP-NEXT:    store i32 0, i32* [[RETVAL]], align 4
 // OMP-NEXT:    store i32 0, i32* [[I]], align 4
-// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB2:@.*]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
 // OMP-NEXT:    call void @foo()
 // OMP-NEXT:    ret i32 0
 //
@@ -41,7 +41,7 @@ void foo(void);
 // NOOMP-NEXT:    [[TMP2:%.*]] = load i32, i32* [[I]], align 4
 // NOOMP-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP2]], 1
 // NOOMP-NEXT:    store i32 [[INC]], i32* [[I]], align 4
-// NOOMP-NEXT:    br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
+// NOOMP-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
 // NOOMP:       for.end:
 // NOOMP-NEXT:    call void @foo()
 // NOOMP-NEXT:    ret i32 0
@@ -63,7 +63,7 @@ int main() {
 // OMP-NEXT:  entry:
 // OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
 // OMP-NEXT:    store i32 0, i32* [[I]], align 4
-// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB2]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB2]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
 // OMP-NEXT:    ret void
 //
 // NOOMP-LABEL: @foo(
@@ -86,7 +86,7 @@ int main() {
 // NOOMP-NEXT:    [[TMP2:%.*]] = load i32, i32* [[I]], align 4
 // NOOMP-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP2]], 1
 // NOOMP-NEXT:    store i32 [[INC]], i32* [[I]], align 4
-// NOOMP-NEXT:    br label [[FOR_COND]], [[LOOP4:!llvm.loop !.*]]
+// NOOMP-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
 // NOOMP:       for.end:
 // NOOMP-NEXT:    ret void
 //

diff  --git a/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected b/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected
index 2069f7e185bb..2c29eb18db6f 100644
--- a/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected
+++ b/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected
@@ -3,7 +3,7 @@
 // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 // CHECK-LABEL: define {{[^@]+}}@test
-// CHECK-SAME: (i64 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0:#.*]] {
+// CHECK-SAME: (i64 [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
 // CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
@@ -21,7 +21,7 @@ long test(long a, int b) {
 
 // A function with a mangled name
 // CHECK-LABEL: define {{[^@]+}}@_Z4testlii
-// CHECK-SAME: (i64 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR0]] {
+// CHECK-SAME: (i64 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
 // CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.funcattrs.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.funcattrs.expected
index e98e62f62b0a..9006888d9c76 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.funcattrs.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.funcattrs.expected
@@ -10,14 +10,14 @@
 define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable willreturn
 ; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
-; IS__TUNIT____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) [[ATTR0:#.*]] {
+; IS__TUNIT____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) #[[ATTR0:[0-9]+]] {
 ; IS__TUNIT____-NEXT:  entry:
 ; IS__TUNIT____-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
 ; IS__TUNIT____-NEXT:    ret i32* [[ARRAYIDX]]
 ;
 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn
 ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
-; IS__CGSCC____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) [[ATTR0:#.*]] {
+; IS__CGSCC____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) #[[ATTR0:[0-9]+]] {
 ; IS__CGSCC____-NEXT:  entry:
 ; IS__CGSCC____-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
 ; IS__CGSCC____-NEXT:    ret i32* [[ARRAYIDX]]

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.plain.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.plain.expected
index ea9d3f44d9ac..7adfa5888dd3 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.plain.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.plain.expected
@@ -9,7 +9,7 @@
 
 define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
 ; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (%struct.ST* nofree readnone [[S:%.*]]) [[ATTR0:#.*]] {
+; CHECK-SAME: (%struct.ST* nofree readnone [[S:%.*]]) #[[ATTR0:[0-9]+]] {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
 ; CHECK-NEXT:    ret i32* [[ARRAYIDX]]

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll
index f19d6dd1f042..28e90cbb4264 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll
@@ -2,6 +2,8 @@
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.14.0"
 
+ at G = external dso_local global i32, align 4
+
 define void @foo(i32) {
   %2 = icmp eq i32 %0, 0
   tail call void @_Z10sideeffectv()

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.expected
index e34e2c2d1a68..6082c9d9b1a3 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.expected
@@ -3,6 +3,8 @@
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.14.0"
 
+ at G = external dso_local global i32, align 4
+
 define void @foo(i32) {
   %2 = icmp eq i32 %0, 0
   tail call void @_Z10sideeffectv()
@@ -38,7 +40,7 @@ declare void @_Z10sideeffectv()
 ; CHECK-NEXT:    tail call void @_Z10sideeffectv()
 ; CHECK-NEXT:    br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
 ; CHECK:       codeRepl:
-; CHECK-NEXT:    call void @foo.cold.1() [[ATTR2:#.*]]
+; CHECK-NEXT:    call void @foo.cold.1() #[[ATTR2:[0-9]+]]
 ; CHECK-NEXT:    ret void
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
@@ -49,7 +51,7 @@ declare void @_Z10sideeffectv()
 ; CHECK-NEXT:    tail call void @_Z10sideeffectv()
 ; CHECK-NEXT:    br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
 ; CHECK:       codeRepl:
-; CHECK-NEXT:    call void @bar.cold.1() [[ATTR2]]
+; CHECK-NEXT:    call void @bar.cold.1() #[[ATTR2]]
 ; CHECK-NEXT:    ret void
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.globals.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.globals.expected
new file mode 100644
index 000000000000..9da822a1d2dc
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.generated.globals.expected
@@ -0,0 +1,84 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs
+; RUN: opt -hotcoldsplit -hotcoldsplit-threshold=0 -S < %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.14.0"
+
+ at G = external dso_local global i32, align 4
+
+define void @foo(i32) {
+  %2 = icmp eq i32 %0, 0
+  tail call void @_Z10sideeffectv()
+  br i1 %2, label %sink, label %exit
+
+sink:
+  tail call void @_Z10sideeffectv()
+  call void @llvm.trap()
+  unreachable
+
+exit:
+  ret void
+}
+
+define void @bar(i32) {
+  %2 = icmp eq i32 %0, 0
+  tail call void @_Z10sideeffectv()
+  br i1 %2, label %sink, label %exit
+
+sink:
+  tail call void @_Z10sideeffectv()
+  call void @llvm.trap()
+  unreachable
+
+exit:
+  ret void
+}
+
+declare void @llvm.trap() noreturn cold
+declare void @_Z10sideeffectv()
+;.
+; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = external dso_local global i32, align 4
+;.
+; CHECK-LABEL: @foo(
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 0
+; CHECK-NEXT:    tail call void @_Z10sideeffectv()
+; CHECK-NEXT:    br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
+; CHECK:       codeRepl:
+; CHECK-NEXT:    call void @foo.cold.1() #[[ATTR2:[0-9]+]]
+; CHECK-NEXT:    ret void
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+;
+; CHECK-LABEL: @bar(
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 0
+; CHECK-NEXT:    tail call void @_Z10sideeffectv()
+; CHECK-NEXT:    br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
+; CHECK:       codeRepl:
+; CHECK-NEXT:    call void @bar.cold.1() #[[ATTR2]]
+; CHECK-NEXT:    ret void
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+;
+; CHECK-LABEL: @foo.cold.1(
+; CHECK-NEXT:  newFuncRoot:
+; CHECK-NEXT:    br label [[SINK:%.*]]
+; CHECK:       sink:
+; CHECK-NEXT:    tail call void @_Z10sideeffectv()
+; CHECK-NEXT:    call void @llvm.trap()
+; CHECK-NEXT:    unreachable
+;
+;
+; CHECK-LABEL: @bar.cold.1(
+; CHECK-NEXT:  newFuncRoot:
+; CHECK-NEXT:    br label [[SINK:%.*]]
+; CHECK:       sink:
+; CHECK-NEXT:    tail call void @_Z10sideeffectv()
+; CHECK-NEXT:    call void @llvm.trap()
+; CHECK-NEXT:    unreachable
+;
+;.
+; CHECK: attributes #[[ATTR0:[0-9]+]] = { cold noreturn nounwind }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { cold minsize noreturn }
+; CHECK: attributes #[[ATTR2]] = { noinline }
+;.

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.expected
index fcd39c147006..37d5148b4572 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.expected
@@ -3,13 +3,15 @@
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.14.0"
 
+ at G = external dso_local global i32, align 4
+
 define void @foo(i32) {
 ; CHECK-LABEL: @foo(
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 0
 ; CHECK-NEXT:    tail call void @_Z10sideeffectv()
 ; CHECK-NEXT:    br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
 ; CHECK:       codeRepl:
-; CHECK-NEXT:    call void @foo.cold.1() [[ATTR2:#.*]]
+; CHECK-NEXT:    call void @foo.cold.1() #[[ATTR2:[0-9]+]]
 ; CHECK-NEXT:    ret void
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
@@ -33,7 +35,7 @@ define void @bar(i32) {
 ; CHECK-NEXT:    tail call void @_Z10sideeffectv()
 ; CHECK-NEXT:    br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
 ; CHECK:       codeRepl:
-; CHECK-NEXT:    call void @bar.cold.1() [[ATTR2]]
+; CHECK-NEXT:    call void @bar.cold.1() #[[ATTR2]]
 ; CHECK-NEXT:    ret void
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.globals.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.globals.expected
new file mode 100644
index 000000000000..c89c282eaf1d
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/generated_funcs.ll.nogenerated.globals.expected
@@ -0,0 +1,65 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
+; RUN: opt -hotcoldsplit -hotcoldsplit-threshold=0 -S < %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.14.0"
+
+ at G = external dso_local global i32, align 4
+
+;.
+; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = external dso_local global i32, align 4
+;.
+define void @foo(i32) {
+; CHECK-LABEL: @foo(
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 0
+; CHECK-NEXT:    tail call void @_Z10sideeffectv()
+; CHECK-NEXT:    br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
+; CHECK:       codeRepl:
+; CHECK-NEXT:    call void @foo.cold.1() #[[ATTR2:[0-9]+]]
+; CHECK-NEXT:    ret void
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+  %2 = icmp eq i32 %0, 0
+  tail call void @_Z10sideeffectv()
+  br i1 %2, label %sink, label %exit
+
+sink:
+  tail call void @_Z10sideeffectv()
+  call void @llvm.trap()
+  unreachable
+
+exit:
+  ret void
+}
+
+define void @bar(i32) {
+; CHECK-LABEL: @bar(
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 0
+; CHECK-NEXT:    tail call void @_Z10sideeffectv()
+; CHECK-NEXT:    br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
+; CHECK:       codeRepl:
+; CHECK-NEXT:    call void @bar.cold.1() #[[ATTR2]]
+; CHECK-NEXT:    ret void
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+  %2 = icmp eq i32 %0, 0
+  tail call void @_Z10sideeffectv()
+  br i1 %2, label %sink, label %exit
+
+sink:
+  tail call void @_Z10sideeffectv()
+  call void @llvm.trap()
+  unreachable
+
+exit:
+  ret void
+}
+
+declare void @llvm.trap() noreturn cold
+declare void @_Z10sideeffectv()
+;.
+; CHECK: attributes #[[ATTR0:[0-9]+]] = { cold noreturn nounwind }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { cold minsize noreturn }
+; CHECK: attributes #[[ATTR2]] = { noinline }
+;.

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.plain.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.plain.expected
index 11934b86c0bb..fc6688daeb92 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.plain.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.plain.expected
@@ -5,7 +5,7 @@ declare void @foo()
 
 define internal void @bar() {
 ; CHECK-LABEL: @bar(
-; CHECK-NEXT:    call void @foo() [[ATTR0:#.*]]
+; CHECK-NEXT:    call void @foo() #[[ATTR0:[0-9]+]]
 ; CHECK-NEXT:    ret void
 ;
   call void @foo() readnone

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.expected
index b33ea0488123..6a17adaaaf34 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.expected
@@ -13,37 +13,37 @@ define dso_local void @foo(i32* %A) #0 !dbg !7 {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32*, align 8
 ; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32* [[A:%.*]], i32** [[A_ADDR]], align 8, [[TBAA16:!tbaa !.*]]
-; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], [[META13:metadata !.*]], metadata !DIExpression()), [[DBG20:!dbg !.*]]
-; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, [[DBG21:!dbg !.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) [[ATTR3:#.*]], [[DBG21]]
-; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], [[META14:metadata !.*]], metadata !DIExpression()), [[DBG22:!dbg !.*]]
-; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, [[DBG22]], [[TBAA23:!tbaa !.*]]
-; CHECK-NEXT:    br label [[FOR_COND:%.*]], [[DBG21]]
+; CHECK-NEXT:    store i32* [[A:%.*]], i32** [[A_ADDR]], align 8, !tbaa [[TBAA16:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META13:![0-9]+]], metadata !DIExpression()), !dbg [[DBG20:![0-9]+]]
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG21:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR3:[0-9]+]], !dbg [[DBG21]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META14:![0-9]+]], metadata !DIExpression()), !dbg [[DBG22:![0-9]+]]
+; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, !dbg [[DBG22]], !tbaa [[TBAA23:![0-9]+]]
+; CHECK-NEXT:    br label [[FOR_COND:%.*]], !dbg [[DBG21]]
 ; CHECK:       for.cond:
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, [[DBG25:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG27:!dbg !.*]], [[TBAA16]]
-; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, [[DBG28:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], [[DBG29:!dbg !.*]]
-; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], [[DBG30:!dbg !.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG25:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG27:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG28:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], !dbg [[DBG29:![0-9]+]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], !dbg [[DBG30:![0-9]+]]
 ; CHECK:       for.cond.cleanup:
-; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, [[DBG31:!dbg !.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) [[ATTR3]], [[DBG31]]
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG31:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR3]], !dbg [[DBG31]]
 ; CHECK-NEXT:    br label [[FOR_END:%.*]]
 ; CHECK:       for.body:
-; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG32:!dbg !.*]], [[TBAA16]]
-; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, [[DBG33:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, [[DBG32]]
-; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], [[DBG32]]
-; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, [[DBG34:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_INC:%.*]], [[DBG32]]
+; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG32:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG33:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, !dbg [[DBG32]]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], !dbg [[DBG32]]
+; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, !dbg [[DBG34:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_INC:%.*]], !dbg [[DBG32]]
 ; CHECK:       for.inc:
-; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, [[DBG35:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, [[DBG35]]
-; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, [[DBG35]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_COND]], [[DBG31]], [[LOOP36:!llvm.loop !.*]]
+; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG35:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, !dbg [[DBG35]]
+; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, !dbg [[DBG35]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_COND]], !dbg [[DBG31]], !llvm.loop [[LOOP36:![0-9]+]]
 ; CHECK:       for.end:
-; CHECK-NEXT:    ret void, [[DBG38:!dbg !.*]]
+; CHECK-NEXT:    ret void, !dbg [[DBG38:![0-9]+]]
 ;
 entry:
   %A.addr = alloca i32*, align 8
@@ -101,37 +101,37 @@ define dso_local void @bar(i32* %A) #0 !dbg !39 {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32*, align 8
 ; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32* [[A:%.*]], i32** [[A_ADDR]], align 8, [[TBAA16]]
-; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], [[META41:metadata !.*]], metadata !DIExpression()), [[DBG44:!dbg !.*]]
-; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, [[DBG45:!dbg !.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) [[ATTR3]], [[DBG45]]
-; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], [[META42:metadata !.*]], metadata !DIExpression()), [[DBG46:!dbg !.*]]
-; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, [[DBG46]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_COND:%.*]], [[DBG45]]
+; CHECK-NEXT:    store i32* [[A:%.*]], i32** [[A_ADDR]], align 8, !tbaa [[TBAA16]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META41:![0-9]+]], metadata !DIExpression()), !dbg [[DBG44:![0-9]+]]
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG45:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR3]], !dbg [[DBG45]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META42:![0-9]+]], metadata !DIExpression()), !dbg [[DBG46:![0-9]+]]
+; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, !dbg [[DBG46]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_COND:%.*]], !dbg [[DBG45]]
 ; CHECK:       for.cond:
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, [[DBG47:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG49:!dbg !.*]], [[TBAA16]]
-; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, [[DBG50:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], [[DBG51:!dbg !.*]]
-; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], [[DBG52:!dbg !.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG47:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG49:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG50:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], !dbg [[DBG51:![0-9]+]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], !dbg [[DBG52:![0-9]+]]
 ; CHECK:       for.cond.cleanup:
-; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, [[DBG53:!dbg !.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) [[ATTR3]], [[DBG53]]
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG53:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR3]], !dbg [[DBG53]]
 ; CHECK-NEXT:    br label [[FOR_END:%.*]]
 ; CHECK:       for.body:
-; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG54:!dbg !.*]], [[TBAA16]]
-; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, [[DBG55:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, [[DBG54]]
-; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], [[DBG54]]
-; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, [[DBG56:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_INC:%.*]], [[DBG54]]
+; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG54:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG55:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, !dbg [[DBG54]]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], !dbg [[DBG54]]
+; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, !dbg [[DBG56:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_INC:%.*]], !dbg [[DBG54]]
 ; CHECK:       for.inc:
-; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, [[DBG57:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, [[DBG57]]
-; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, [[DBG57]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_COND]], [[DBG53]], [[LOOP58:!llvm.loop !.*]]
+; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG57:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, !dbg [[DBG57]]
+; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, !dbg [[DBG57]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_COND]], !dbg [[DBG53]], !llvm.loop [[LOOP58:![0-9]+]]
 ; CHECK:       for.end:
-; CHECK-NEXT:    ret void, [[DBG60:!dbg !.*]]
+; CHECK-NEXT:    ret void, !dbg [[DBG60:![0-9]+]]
 ;
 entry:
   %A.addr = alloca i32*, align 8

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.expected
index 5a7d734cfab1..89d7b7e00fe3 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.expected
@@ -10,41 +10,41 @@ target triple = "x86_64-unknown-linux-gnu"
 ; Function Attrs: nounwind uwtable
 define dso_local void @foo(i32* %A) #0 !dbg !7 {
 ; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i32* [[A:%.*]]) [[ATTR0:#.*]] [[DBG7:!dbg !.*]] {
+; CHECK-SAME: (i32* [[A:%.*]]) #[[ATTR0:[0-9]+]] !dbg [[DBG7:![0-9]+]] {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32*, align 8
 ; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32* [[A]], i32** [[A_ADDR]], align 8, [[TBAA16:!tbaa !.*]]
-; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], [[META13:metadata !.*]], metadata !DIExpression()), [[DBG20:!dbg !.*]]
-; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, [[DBG21:!dbg !.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) [[ATTR3:#.*]], [[DBG21]]
-; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], [[META14:metadata !.*]], metadata !DIExpression()), [[DBG22:!dbg !.*]]
-; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, [[DBG22]], [[TBAA23:!tbaa !.*]]
-; CHECK-NEXT:    br label [[FOR_COND:%.*]], [[DBG21]]
+; CHECK-NEXT:    store i32* [[A]], i32** [[A_ADDR]], align 8, !tbaa [[TBAA16:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META13:![0-9]+]], metadata !DIExpression()), !dbg [[DBG20:![0-9]+]]
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG21:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR3:[0-9]+]], !dbg [[DBG21]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META14:![0-9]+]], metadata !DIExpression()), !dbg [[DBG22:![0-9]+]]
+; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, !dbg [[DBG22]], !tbaa [[TBAA23:![0-9]+]]
+; CHECK-NEXT:    br label [[FOR_COND:%.*]], !dbg [[DBG21]]
 ; CHECK:       for.cond:
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, [[DBG25:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG27:!dbg !.*]], [[TBAA16]]
-; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, [[DBG28:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], [[DBG29:!dbg !.*]]
-; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], [[DBG30:!dbg !.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG25:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG27:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG28:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], !dbg [[DBG29:![0-9]+]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], !dbg [[DBG30:![0-9]+]]
 ; CHECK:       for.cond.cleanup:
-; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, [[DBG31:!dbg !.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) [[ATTR3]], [[DBG31]]
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG31:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR3]], !dbg [[DBG31]]
 ; CHECK-NEXT:    br label [[FOR_END:%.*]]
 ; CHECK:       for.body:
-; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG32:!dbg !.*]], [[TBAA16]]
-; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, [[DBG33:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, [[DBG32]]
-; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], [[DBG32]]
-; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, [[DBG34:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_INC:%.*]], [[DBG32]]
+; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG32:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG33:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, !dbg [[DBG32]]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], !dbg [[DBG32]]
+; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, !dbg [[DBG34:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_INC:%.*]], !dbg [[DBG32]]
 ; CHECK:       for.inc:
-; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, [[DBG35:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, [[DBG35]]
-; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, [[DBG35]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_COND]], [[DBG31]], [[LOOP36:!llvm.loop !.*]]
+; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG35:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, !dbg [[DBG35]]
+; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, !dbg [[DBG35]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_COND]], !dbg [[DBG31]], !llvm.loop [[LOOP36:![0-9]+]]
 ; CHECK:       for.end:
-; CHECK-NEXT:    ret void, [[DBG38:!dbg !.*]]
+; CHECK-NEXT:    ret void, !dbg [[DBG38:![0-9]+]]
 ;
 entry:
   %A.addr = alloca i32*, align 8
@@ -99,41 +99,41 @@ declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #2
 ; Function Attrs: nounwind uwtable
 define dso_local void @bar(i32* %A) #0 !dbg !39 {
 ; CHECK-LABEL: define {{[^@]+}}@bar
-; CHECK-SAME: (i32* [[A:%.*]]) [[ATTR0]] [[DBG39:!dbg !.*]] {
+; CHECK-SAME: (i32* [[A:%.*]]) #[[ATTR0]] !dbg [[DBG39:![0-9]+]] {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32*, align 8
 ; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32* [[A]], i32** [[A_ADDR]], align 8, [[TBAA16]]
-; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], [[META41:metadata !.*]], metadata !DIExpression()), [[DBG44:!dbg !.*]]
-; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, [[DBG45:!dbg !.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) [[ATTR3]], [[DBG45]]
-; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], [[META42:metadata !.*]], metadata !DIExpression()), [[DBG46:!dbg !.*]]
-; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, [[DBG46]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_COND:%.*]], [[DBG45]]
+; CHECK-NEXT:    store i32* [[A]], i32** [[A_ADDR]], align 8, !tbaa [[TBAA16]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META41:![0-9]+]], metadata !DIExpression()), !dbg [[DBG44:![0-9]+]]
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG45:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR3]], !dbg [[DBG45]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META42:![0-9]+]], metadata !DIExpression()), !dbg [[DBG46:![0-9]+]]
+; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, !dbg [[DBG46]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_COND:%.*]], !dbg [[DBG45]]
 ; CHECK:       for.cond:
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, [[DBG47:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG49:!dbg !.*]], [[TBAA16]]
-; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, [[DBG50:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], [[DBG51:!dbg !.*]]
-; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], [[DBG52:!dbg !.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG47:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG49:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG50:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], !dbg [[DBG51:![0-9]+]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], !dbg [[DBG52:![0-9]+]]
 ; CHECK:       for.cond.cleanup:
-; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, [[DBG53:!dbg !.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) [[ATTR3]], [[DBG53]]
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG53:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR3]], !dbg [[DBG53]]
 ; CHECK-NEXT:    br label [[FOR_END:%.*]]
 ; CHECK:       for.body:
-; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG54:!dbg !.*]], [[TBAA16]]
-; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, [[DBG55:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, [[DBG54]]
-; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], [[DBG54]]
-; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, [[DBG56:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_INC:%.*]], [[DBG54]]
+; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG54:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG55:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, !dbg [[DBG54]]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], !dbg [[DBG54]]
+; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, !dbg [[DBG56:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_INC:%.*]], !dbg [[DBG54]]
 ; CHECK:       for.inc:
-; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, [[DBG57:!dbg !.*]], [[TBAA23]]
-; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, [[DBG57]]
-; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, [[DBG57]], [[TBAA23]]
-; CHECK-NEXT:    br label [[FOR_COND]], [[DBG53]], [[LOOP58:!llvm.loop !.*]]
+; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG57:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, !dbg [[DBG57]]
+; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, !dbg [[DBG57]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_COND]], !dbg [[DBG53]], !llvm.loop [[LOOP58:![0-9]+]]
 ; CHECK:       for.end:
-; CHECK-NEXT:    ret void, [[DBG60:!dbg !.*]]
+; CHECK-NEXT:    ret void, !dbg [[DBG60:![0-9]+]]
 ;
 entry:
   %A.addr = alloca i32*, align 8

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.globals.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.globals.expected
new file mode 100644
index 000000000000..741a8b0c2493
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.globals.expected
@@ -0,0 +1,316 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals
+; Just run it through opt, no passes needed.
+; RUN: opt < %s -S | FileCheck %s
+
+; ModuleID = 'various_ir_values.c'
+source_filename = "various_ir_values.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define dso_local void @foo(i32* %A) #0 !dbg !7 {
+; CHECK-LABEL: define {{[^@]+}}@foo
+; CHECK-SAME: (i32* [[A:%.*]]) #[[ATTR0:[0-9]+]] !dbg [[DBG7:![0-9]+]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32*, align 8
+; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    store i32* [[A]], i32** [[A_ADDR]], align 8, !tbaa [[TBAA16:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META13:![0-9]+]], metadata !DIExpression()), !dbg [[DBG20:![0-9]+]]
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG21:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR3:[0-9]+]], !dbg [[DBG21]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META14:![0-9]+]], metadata !DIExpression()), !dbg [[DBG22:![0-9]+]]
+; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, !dbg [[DBG22]], !tbaa [[TBAA23:![0-9]+]]
+; CHECK-NEXT:    br label [[FOR_COND:%.*]], !dbg [[DBG21]]
+; CHECK:       for.cond:
+; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG25:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG27:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG28:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], !dbg [[DBG29:![0-9]+]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], !dbg [[DBG30:![0-9]+]]
+; CHECK:       for.cond.cleanup:
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG31:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR3]], !dbg [[DBG31]]
+; CHECK-NEXT:    br label [[FOR_END:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG32:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG33:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, !dbg [[DBG32]]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], !dbg [[DBG32]]
+; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, !dbg [[DBG34:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_INC:%.*]], !dbg [[DBG32]]
+; CHECK:       for.inc:
+; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG35:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, !dbg [[DBG35]]
+; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, !dbg [[DBG35]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_COND]], !dbg [[DBG31]], !llvm.loop [[LOOP36:![0-9]+]]
+; CHECK:       for.end:
+; CHECK-NEXT:    ret void, !dbg [[DBG38:![0-9]+]]
+;
+entry:
+  %A.addr = alloca i32*, align 8
+  %i = alloca i32, align 4
+  store i32* %A, i32** %A.addr, align 8, !tbaa !16
+  call void @llvm.dbg.declare(metadata i32** %A.addr, metadata !13, metadata !DIExpression()), !dbg !20
+  %0 = bitcast i32* %i to i8*, !dbg !21
+  call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #3, !dbg !21
+  call void @llvm.dbg.declare(metadata i32* %i, metadata !14, metadata !DIExpression()), !dbg !22
+  store i32 0, i32* %i, align 4, !dbg !22, !tbaa !23
+  br label %for.cond, !dbg !21
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %1 = load i32, i32* %i, align 4, !dbg !25, !tbaa !23
+  %2 = load i32*, i32** %A.addr, align 8, !dbg !27, !tbaa !16
+  %3 = load i32, i32* %2, align 4, !dbg !28, !tbaa !23
+  %cmp = icmp slt i32 %1, %3, !dbg !29
+  br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !30
+
+for.cond.cleanup:                                 ; preds = %for.cond
+  %4 = bitcast i32* %i to i8*, !dbg !31
+  call void @llvm.lifetime.end.p0i8(i64 4, i8* %4) #3, !dbg !31
+  br label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %5 = load i32*, i32** %A.addr, align 8, !dbg !32, !tbaa !16
+  %6 = load i32, i32* %i, align 4, !dbg !33, !tbaa !23
+  %idxprom = sext i32 %6 to i64, !dbg !32
+  %arrayidx = getelementptr inbounds i32, i32* %5, i64 %idxprom, !dbg !32
+  store i32 0, i32* %arrayidx, align 4, !dbg !34, !tbaa !23
+  br label %for.inc, !dbg !32
+
+for.inc:                                          ; preds = %for.body
+  %7 = load i32, i32* %i, align 4, !dbg !35, !tbaa !23
+  %inc = add nsw i32 %7, 1, !dbg !35
+  store i32 %inc, i32* %i, align 4, !dbg !35, !tbaa !23
+  br label %for.cond, !dbg !31, !llvm.loop !36
+
+for.end:                                          ; preds = %for.cond.cleanup
+  ret void, !dbg !38
+}
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #2
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #2
+
+; Function Attrs: nounwind uwtable
+define dso_local void @bar(i32* %A) #0 !dbg !39 {
+; CHECK-LABEL: define {{[^@]+}}@bar
+; CHECK-SAME: (i32* [[A:%.*]]) #[[ATTR0]] !dbg [[DBG39:![0-9]+]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32*, align 8
+; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    store i32* [[A]], i32** [[A_ADDR]], align 8, !tbaa [[TBAA16]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META41:![0-9]+]], metadata !DIExpression()), !dbg [[DBG44:![0-9]+]]
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG45:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR3]], !dbg [[DBG45]]
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META42:![0-9]+]], metadata !DIExpression()), !dbg [[DBG46:![0-9]+]]
+; CHECK-NEXT:    store i32 0, i32* [[I]], align 4, !dbg [[DBG46]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_COND:%.*]], !dbg [[DBG45]]
+; CHECK:       for.cond:
+; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG47:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG49:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG50:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], !dbg [[DBG51:![0-9]+]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], !dbg [[DBG52:![0-9]+]]
+; CHECK:       for.cond.cleanup:
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, !dbg [[DBG53:![0-9]+]]
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR3]], !dbg [[DBG53]]
+; CHECK-NEXT:    br label [[FOR_END:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG54:![0-9]+]], !tbaa [[TBAA16]]
+; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG55:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, !dbg [[DBG54]]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], !dbg [[DBG54]]
+; CHECK-NEXT:    store i32 0, i32* [[ARRAYIDX]], align 4, !dbg [[DBG56:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_INC:%.*]], !dbg [[DBG54]]
+; CHECK:       for.inc:
+; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I]], align 4, !dbg [[DBG57:![0-9]+]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1, !dbg [[DBG57]]
+; CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4, !dbg [[DBG57]], !tbaa [[TBAA23]]
+; CHECK-NEXT:    br label [[FOR_COND]], !dbg [[DBG53]], !llvm.loop [[LOOP58:![0-9]+]]
+; CHECK:       for.end:
+; CHECK-NEXT:    ret void, !dbg [[DBG60:![0-9]+]]
+;
+entry:
+  %A.addr = alloca i32*, align 8
+  %i = alloca i32, align 4
+  store i32* %A, i32** %A.addr, align 8, !tbaa !16
+  call void @llvm.dbg.declare(metadata i32** %A.addr, metadata !41, metadata !DIExpression()), !dbg !44
+  %0 = bitcast i32* %i to i8*, !dbg !45
+  call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #3, !dbg !45
+  call void @llvm.dbg.declare(metadata i32* %i, metadata !42, metadata !DIExpression()), !dbg !46
+  store i32 0, i32* %i, align 4, !dbg !46, !tbaa !23
+  br label %for.cond, !dbg !45
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %1 = load i32, i32* %i, align 4, !dbg !47, !tbaa !23
+  %2 = load i32*, i32** %A.addr, align 8, !dbg !49, !tbaa !16
+  %3 = load i32, i32* %2, align 4, !dbg !50, !tbaa !23
+  %cmp = icmp slt i32 %1, %3, !dbg !51
+  br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !52
+
+for.cond.cleanup:                                 ; preds = %for.cond
+  %4 = bitcast i32* %i to i8*, !dbg !53
+  call void @llvm.lifetime.end.p0i8(i64 4, i8* %4) #3, !dbg !53
+  br label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %5 = load i32*, i32** %A.addr, align 8, !dbg !54, !tbaa !16
+  %6 = load i32, i32* %i, align 4, !dbg !55, !tbaa !23
+  %idxprom = sext i32 %6 to i64, !dbg !54
+  %arrayidx = getelementptr inbounds i32, i32* %5, i64 %idxprom, !dbg !54
+  store i32 0, i32* %arrayidx, align 4, !dbg !56, !tbaa !23
+  br label %for.inc, !dbg !54
+
+for.inc:                                          ; preds = %for.body
+  %7 = load i32, i32* %i, align 4, !dbg !57, !tbaa !23
+  %inc = add nsw i32 %7, 1, !dbg !57
+  store i32 %inc, i32* %i, align 4, !dbg !57, !tbaa !23
+  br label %for.cond, !dbg !53, !llvm.loop !58
+
+for.end:                                          ; preds = %for.cond.cleanup
+  ret void, !dbg !60
+}
+
+attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone speculatable willreturn }
+attributes #2 = { argmemonly nounwind willreturn }
+attributes #3 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (git at github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "various_ir_values.c", directory: "/data/build/llvm-project")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 11.0.0 (git at github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)"}
+!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null, !10}
+!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !{!13, !14}
+!13 = !DILocalVariable(name: "A", arg: 1, scope: !7, file: !1, line: 1, type: !10)
+!14 = !DILocalVariable(name: "i", scope: !15, file: !1, line: 3, type: !11)
+!15 = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 3)
+!16 = !{!17, !17, i64 0}
+!17 = !{!"any pointer", !18, i64 0}
+!18 = !{!"omnipotent char", !19, i64 0}
+!19 = !{!"Simple C/C++ TBAA"}
+!20 = !DILocation(line: 1, column: 15, scope: !7)
+!21 = !DILocation(line: 3, column: 8, scope: !15)
+!22 = !DILocation(line: 3, column: 12, scope: !15)
+!23 = !{!24, !24, i64 0}
+!24 = !{!"int", !18, i64 0}
+!25 = !DILocation(line: 3, column: 19, scope: !26)
+!26 = distinct !DILexicalBlock(scope: !15, file: !1, line: 3, column: 3)
+!27 = !DILocation(line: 3, column: 24, scope: !26)
+!28 = !DILocation(line: 3, column: 23, scope: !26)
+!29 = !DILocation(line: 3, column: 21, scope: !26)
+!30 = !DILocation(line: 3, column: 3, scope: !15)
+!31 = !DILocation(line: 3, column: 3, scope: !26)
+!32 = !DILocation(line: 4, column: 5, scope: !26)
+!33 = !DILocation(line: 4, column: 7, scope: !26)
+!34 = !DILocation(line: 4, column: 10, scope: !26)
+!35 = !DILocation(line: 3, column: 27, scope: !26)
+!36 = distinct !{!36, !30, !37}
+!37 = !DILocation(line: 4, column: 12, scope: !15)
+!38 = !DILocation(line: 5, column: 1, scope: !7)
+!39 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 7, type: !8, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !40)
+!40 = !{!41, !42}
+!41 = !DILocalVariable(name: "A", arg: 1, scope: !39, file: !1, line: 7, type: !10)
+!42 = !DILocalVariable(name: "i", scope: !43, file: !1, line: 9, type: !11)
+!43 = distinct !DILexicalBlock(scope: !39, file: !1, line: 9, column: 3)
+!44 = !DILocation(line: 7, column: 15, scope: !39)
+!45 = !DILocation(line: 9, column: 8, scope: !43)
+!46 = !DILocation(line: 9, column: 12, scope: !43)
+!47 = !DILocation(line: 9, column: 19, scope: !48)
+!48 = distinct !DILexicalBlock(scope: !43, file: !1, line: 9, column: 3)
+!49 = !DILocation(line: 9, column: 24, scope: !48)
+!50 = !DILocation(line: 9, column: 23, scope: !48)
+!51 = !DILocation(line: 9, column: 21, scope: !48)
+!52 = !DILocation(line: 9, column: 3, scope: !43)
+!53 = !DILocation(line: 9, column: 3, scope: !48)
+!54 = !DILocation(line: 10, column: 5, scope: !48)
+!55 = !DILocation(line: 10, column: 7, scope: !48)
+!56 = !DILocation(line: 10, column: 10, scope: !48)
+!57 = !DILocation(line: 9, column: 27, scope: !48)
+!58 = distinct !{!58, !52, !59}
+!59 = !DILocation(line: 10, column: 12, scope: !43)
+!60 = !DILocation(line: 11, column: 1, scope: !39)
+;.
+; CHECK: attributes #[[ATTR0]] = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn }
+; CHECK: attributes #[[ATTR2:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
+; CHECK: attributes #[[ATTR3]] = { nounwind }
+;.
+; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (git at github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+; CHECK: [[META1:![0-9]+]] = !DIFile(filename: "various_ir_values.c", directory: "/data/build/llvm-project")
+; CHECK: [[META2:![0-9]+]] = !{}
+; CHECK: [[META3:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 4}
+; CHECK: [[META4:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
+; CHECK: [[META5:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+; CHECK: [[META6:![0-9]+]] = !{!"clang version 11.0.0 (git at github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)"}
+; CHECK: [[DBG7]] = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
+; CHECK: [[META8:![0-9]+]] = !DISubroutineType(types: !9)
+; CHECK: [[META9:![0-9]+]] = !{null, !10}
+; CHECK: [[META10:![0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
+; CHECK: [[META11:![0-9]+]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+; CHECK: [[META12:![0-9]+]] = !{!13, !14}
+; CHECK: [[META13]] = !DILocalVariable(name: "A", arg: 1, scope: !7, file: !1, line: 1, type: !10)
+; CHECK: [[META14]] = !DILocalVariable(name: "i", scope: !15, file: !1, line: 3, type: !11)
+; CHECK: [[META15:![0-9]+]] = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 3)
+; CHECK: [[TBAA16]] = !{!17, !17, i64 0}
+; CHECK: [[META17:![0-9]+]] = !{!"any pointer", !18, i64 0}
+; CHECK: [[META18:![0-9]+]] = !{!"omnipotent char", !19, i64 0}
+; CHECK: [[META19:![0-9]+]] = !{!"Simple C/C++ TBAA"}
+; CHECK: [[DBG20]] = !DILocation(line: 1, column: 15, scope: !7)
+; CHECK: [[DBG21]] = !DILocation(line: 3, column: 8, scope: !15)
+; CHECK: [[DBG22]] = !DILocation(line: 3, column: 12, scope: !15)
+; CHECK: [[TBAA23]] = !{!24, !24, i64 0}
+; CHECK: [[META24:![0-9]+]] = !{!"int", !18, i64 0}
+; CHECK: [[DBG25]] = !DILocation(line: 3, column: 19, scope: !26)
+; CHECK: [[META26:![0-9]+]] = distinct !DILexicalBlock(scope: !15, file: !1, line: 3, column: 3)
+; CHECK: [[DBG27]] = !DILocation(line: 3, column: 24, scope: !26)
+; CHECK: [[DBG28]] = !DILocation(line: 3, column: 23, scope: !26)
+; CHECK: [[DBG29]] = !DILocation(line: 3, column: 21, scope: !26)
+; CHECK: [[DBG30]] = !DILocation(line: 3, column: 3, scope: !15)
+; CHECK: [[DBG31]] = !DILocation(line: 3, column: 3, scope: !26)
+; CHECK: [[DBG32]] = !DILocation(line: 4, column: 5, scope: !26)
+; CHECK: [[DBG33]] = !DILocation(line: 4, column: 7, scope: !26)
+; CHECK: [[DBG34]] = !DILocation(line: 4, column: 10, scope: !26)
+; CHECK: [[DBG35]] = !DILocation(line: 3, column: 27, scope: !26)
+; CHECK: [[LOOP36]] = distinct !{!36, !30, !37}
+; CHECK: [[META37:![0-9]+]] = !DILocation(line: 4, column: 12, scope: !15)
+; CHECK: [[DBG38]] = !DILocation(line: 5, column: 1, scope: !7)
+; CHECK: [[DBG39]] = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 7, type: !8, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !40)
+; CHECK: [[META40:![0-9]+]] = !{!41, !42}
+; CHECK: [[META41]] = !DILocalVariable(name: "A", arg: 1, scope: !39, file: !1, line: 7, type: !10)
+; CHECK: [[META42]] = !DILocalVariable(name: "i", scope: !43, file: !1, line: 9, type: !11)
+; CHECK: [[META43:![0-9]+]] = distinct !DILexicalBlock(scope: !39, file: !1, line: 9, column: 3)
+; CHECK: [[DBG44]] = !DILocation(line: 7, column: 15, scope: !39)
+; CHECK: [[DBG45]] = !DILocation(line: 9, column: 8, scope: !43)
+; CHECK: [[DBG46]] = !DILocation(line: 9, column: 12, scope: !43)
+; CHECK: [[DBG47]] = !DILocation(line: 9, column: 19, scope: !48)
+; CHECK: [[META48:![0-9]+]] = distinct !DILexicalBlock(scope: !43, file: !1, line: 9, column: 3)
+; CHECK: [[DBG49]] = !DILocation(line: 9, column: 24, scope: !48)
+; CHECK: [[DBG50]] = !DILocation(line: 9, column: 23, scope: !48)
+; CHECK: [[DBG51]] = !DILocation(line: 9, column: 21, scope: !48)
+; CHECK: [[DBG52]] = !DILocation(line: 9, column: 3, scope: !43)
+; CHECK: [[DBG53]] = !DILocation(line: 9, column: 3, scope: !48)
+; CHECK: [[DBG54]] = !DILocation(line: 10, column: 5, scope: !48)
+; CHECK: [[DBG55]] = !DILocation(line: 10, column: 7, scope: !48)
+; CHECK: [[DBG56]] = !DILocation(line: 10, column: 10, scope: !48)
+; CHECK: [[DBG57]] = !DILocation(line: 9, column: 27, scope: !48)
+; CHECK: [[LOOP58]] = distinct !{!58, !52, !59}
+; CHECK: [[META59:![0-9]+]] = !DILocation(line: 10, column: 12, scope: !43)
+; CHECK: [[DBG60]] = !DILocation(line: 11, column: 1, scope: !39)
+;.

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/generated_funcs.test b/llvm/test/tools/UpdateTestChecks/update_test_checks/generated_funcs.test
index 68dead038d2b..8959c593f68c 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/generated_funcs.test
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/generated_funcs.test
@@ -5,6 +5,9 @@
 ## Check that running the script again does not change the result:
 # RUN: %update_test_checks --include-generated-funcs %t.ll
 # RUN: 
diff  -u %t.ll %S/Inputs/generated_funcs.ll.generated.expected
+## Also try the --check-globals flag
+# RUN: %update_test_checks %t.ll --check-globals
+# RUN: 
diff  -u %t.ll %S/Inputs/generated_funcs.ll.generated.globals.expected
 
 ## Check that generated functions are not included.
 # RUN: cp -f %S/Inputs/generated_funcs.ll %t.ll && %update_test_checks %t.ll
@@ -13,3 +16,6 @@
 ## Check that running the script again does not change the result:
 # RUN: %update_test_checks %t.ll
 # RUN: 
diff  -u %t.ll %S/Inputs/generated_funcs.ll.nogenerated.expected
+## Also try the --check-globals flag
+# RUN: %update_test_checks %t.ll --check-globals
+# RUN: 
diff  -u %t.ll %S/Inputs/generated_funcs.ll.nogenerated.globals.expected

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/various_ir_values.test b/llvm/test/tools/UpdateTestChecks/update_test_checks/various_ir_values.test
index 19b63450f5ca..c65150eed0a8 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/various_ir_values.test
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/various_ir_values.test
@@ -13,4 +13,6 @@
 ## added to the update invocation below.
 # RUN: %update_test_checks %t.ll
 # RUN: 
diff  -u %t.ll %S/Inputs/various_ir_values.ll.funcsig.expected
-
+## Also try the --check-globals flag
+# RUN: %update_test_checks %t.ll --check-globals
+# RUN: 
diff  -u %t.ll %S/Inputs/various_ir_values.ll.funcsig.globals.expected

diff  --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 0082c4ecd181..5cf509013f94 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -112,9 +112,12 @@ def itertests(test_patterns, parser, script_name, comment_prefix=None, argparse_
                      comment_prefix, argparse_callback)
 
 
-def should_add_line_to_output(input_line, prefix_set):
+def should_add_line_to_output(input_line, prefix_set, skip_global_checks = False):
   # Skip any blank comment lines in the IR.
-  if input_line.strip() == ';':
+  if not skip_global_checks and input_line.strip() == ';':
+    return False
+  # Skip a special double comment line we use as a separator.
+  if input_line.strip() == SEPARATOR:
     return False
   # Skip any blank lines in the IR.
   #if input_line.strip() == '':
@@ -122,6 +125,9 @@ def should_add_line_to_output(input_line, prefix_set):
   # And skip any CHECK lines. We're building our own.
   m = CHECK_RE.match(input_line)
   if m and m.group(1) in prefix_set:
+    if skip_global_checks:
+      global_ir_value_re = re.compile('\[\[', flags=(re.M))
+      return not global_ir_value_re.search(input_line)
     return False
 
   return True
@@ -177,6 +183,7 @@ def invoke_tool(exe, cmd_args, ir):
     r'# =>This Inner Loop Header:.*|# in Loop:.*', flags=re.M)
 SCRUB_TAILING_COMMENT_TOKEN_RE = re.compile(r'(?<=\S)+[ \t]*#$', flags=re.M)
 
+SEPARATOR = ';.'
 
 def error(msg, test_file=None):
   if test_file:
@@ -237,10 +244,14 @@ def __init__(self, string, extra, args_and_sig, attrs):
   def is_same_except_arg_names(self, extrascrub, args_and_sig, attrs):
     arg_names = set()
     def drop_arg_names(match):
-        arg_names.add(match.group(3))
-        return match.group(1) + match.group(match.lastindex)
+        arg_names.add(match.group(variable_group_in_ir_value_match))
+        if match.group(attribute_group_in_ir_value_match):
+            attr = match.group(attribute_group_in_ir_value_match)
+        else:
+            attr = ''
+        return match.group(1) + attr + match.group(match.lastindex)
     def repl_arg_names(match):
-        if match.group(3) is not None and match.group(3) in arg_names:
+        if match.group(variable_group_in_ir_value_match) is not None and match.group(variable_group_in_ir_value_match) in arg_names:
             return match.group(1) + match.group(match.lastindex)
         return match.group(1) + match.group(2) + match.group(match.lastindex)
     if self.attrs != attrs:
@@ -266,10 +277,12 @@ def __init__(self, run_list, flags, scrubber_args):
     self._scrubber_args = scrubber_args
     self._func_dict = {}
     self._func_order = {}
+    self._global_var_dict = {}
     for tuple in run_list:
       for prefix in tuple[0]:
         self._func_dict.update({prefix:dict()})
         self._func_order.update({prefix: []})
+        self._global_var_dict.update({prefix:dict()})
 
   def finish_and_get_func_dict(self):
     for prefix in self._get_failed_prefixes():
@@ -278,8 +291,12 @@ def finish_and_get_func_dict(self):
 
   def func_order(self):
     return self._func_order
-  
+
+  def global_var_dict(self):
+    return self._global_var_dict
+
   def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes):
+    build_global_values_dictionary(self._global_var_dict, raw_tool_output, prefixes)
     for m in function_re.finditer(raw_tool_output):
       if not m:
         continue
@@ -341,7 +358,7 @@ def _get_failed_prefixes(self):
     # all instances of the prefix. Effectively, this prefix is unused and should
     # be removed.
     for prefix in self._func_dict:
-      if (self._func_dict[prefix] and 
+      if (self._func_dict[prefix] and
           (not [fct for fct in self._func_dict[prefix]
                 if self._func_dict[prefix][fct] is not None])):
         yield prefix
@@ -354,34 +371,59 @@ def _get_failed_prefixes(self):
 # TODO: We should also derive check lines for global, debug, loop declarations, etc..
 
 class NamelessValue:
-    def __init__(self, check_prefix, ir_prefix, ir_regexp):
+    def __init__(self, check_prefix, check_key, ir_prefix, global_ir_prefix, global_ir_prefix_regexp,
+                 ir_regexp, global_ir_rhs_regexp, is_before_functions):
         self.check_prefix = check_prefix
+        self.check_key = check_key
         self.ir_prefix = ir_prefix
+        self.global_ir_prefix = global_ir_prefix
+        self.global_ir_prefix_regexp = global_ir_prefix_regexp
         self.ir_regexp = ir_regexp
+        self.global_ir_rhs_regexp = global_ir_rhs_regexp
+        self.is_before_functions = is_before_functions
 
 # Description of the 
diff erent "unnamed" values we match in the IR, e.g.,
 # (local) ssa values, (debug) metadata, etc.
 nameless_values = [
-    NamelessValue(r'TMP',   r'%',            r'[\w.-]+?'),
-    NamelessValue(r'GLOB',  r'@',            r'[0-9]+?'),
-    NamelessValue(r'ATTR',  r'#',            r'[0-9]+?'),
-    NamelessValue(r'DBG',   r'!dbg !',       r'[0-9]+?'),
-    NamelessValue(r'TBAA',  r'!tbaa !',      r'[0-9]+?'),
-    NamelessValue(r'RNG',   r'!range !',     r'[0-9]+?'),
-    NamelessValue(r'LOOP',  r'!llvm.loop !', r'[0-9]+?'),
-    NamelessValue(r'META',  r'metadata !',   r'[0-9]+?'),
+    NamelessValue(r'TMP'  , '%' , r'%'           , None            , None                   , r'[\w$.-]+?' , None                 , False) ,
+    NamelessValue(r'ATTR' , '#' , r'#'           , None            , None                   , r'[0-9]+'    , None                 , False) ,
+    NamelessValue(r'ATTR' , '#' , None           , r'attributes #' , r'[0-9]+'              , None         , r'{[^}]*}'           , False) ,
+    NamelessValue(r'GLOB' , '@' , r'@'           , None            , None                   , r'[0-9]+'    , None                 , False) ,
+    NamelessValue(r'GLOB' , '@' , None           , r'@'            , r'[a-zA-Z0-9_$"\\.-]+' , None         , r'.+'                , True)  ,
+    NamelessValue(r'DBG'  , '!' , r'!dbg '       , None            , None                   , r'![0-9]+'   , None                 , False) ,
+    NamelessValue(r'TBAA' , '!' , r'!tbaa '      , None            , None                   , r'![0-9]+'   , None                 , False) ,
+    NamelessValue(r'RNG'  , '!' , r'!range '     , None            , None                   , r'![0-9]+'   , None                 , False) ,
+    NamelessValue(r'LOOP' , '!' , r'!llvm.loop ' , None            , None                   , r'![0-9]+'   , None                 , False) ,
+    NamelessValue(r'META' , '!' , r'metadata '   , None            , None                   , r'![0-9]+'   , None                 , False) ,
+    NamelessValue(r'META' , '!' , None           , r''             , r'![0-9]+'             , None         , r'(?:distinct |)!.*' , False) ,
 ]
 
+def createOrRegexp(old, new):
+    if not old:
+        return new
+    if not new:
+        return old
+    return old + '|' + new
+
+def createPrefixMatch(prefix_str, prefix_re):
+    if prefix_str is None or prefix_re is None:
+        return ''
+    return '(?:' + prefix_str + '(' + prefix_re + '))'
+
 # Build the regexp that matches an "IR value". This can be a local variable,
 # argument, global, or metadata, anything that is "named". It is important that
 # the PREFIX and SUFFIX below only contain a single group, if that changes
 # other locations will need adjustment as well.
-IR_VALUE_REGEXP_PREFIX = r'(\s+)'
+IR_VALUE_REGEXP_PREFIX = r'(\s*)'
 IR_VALUE_REGEXP_STRING = r''
 for nameless_value in nameless_values:
-    if IR_VALUE_REGEXP_STRING:
-        IR_VALUE_REGEXP_STRING += '|'
-    IR_VALUE_REGEXP_STRING += nameless_value.ir_prefix + r'(' + nameless_value.ir_regexp + r')'
+    lcl_match = createPrefixMatch(nameless_value.ir_prefix, nameless_value.ir_regexp)
+    glb_match = createPrefixMatch(nameless_value.global_ir_prefix, nameless_value.global_ir_prefix_regexp)
+    assert((lcl_match or glb_match) and not (lcl_match and glb_match))
+    if lcl_match:
+        IR_VALUE_REGEXP_STRING = createOrRegexp(IR_VALUE_REGEXP_STRING, lcl_match)
+    elif glb_match:
+        IR_VALUE_REGEXP_STRING = createOrRegexp(IR_VALUE_REGEXP_STRING, '^' + glb_match)
 IR_VALUE_REGEXP_SUFFIX = r'([,\s\(\)]|\Z)'
 IR_VALUE_RE = re.compile(IR_VALUE_REGEXP_PREFIX + r'(' + IR_VALUE_REGEXP_STRING + r')' + IR_VALUE_REGEXP_SUFFIX)
 
@@ -389,6 +431,10 @@ def __init__(self, check_prefix, ir_prefix, ir_regexp):
 # IR_VALUE_REGEXP_STRING is one group (=2), and then the nameless values start.
 first_nameless_group_in_ir_value_match = 3
 
+# constants for the group id of special matches
+variable_group_in_ir_value_match = 3
+attribute_group_in_ir_value_match = 4
+
 # Check a match for IR_VALUE_RE and inspect it to determine if it was a local
 # value, %..., global @..., debug number !dbg !..., etc. See the PREFIXES above.
 def get_idx_from_ir_value_match(match):
@@ -407,30 +453,61 @@ def get_name_from_ir_value_match(match):
 def get_nameless_check_prefix_from_ir_value_match(match):
     return nameless_values[get_idx_from_ir_value_match(match)].check_prefix
 
-# Return the IR prefix we use for this kind or IR value, e.g., % for locals,
+# Return the IR prefix and check prefix we use for this kind or IR value, e.g., (%, TMP) for locals,
 # see also get_idx_from_ir_value_match
 def get_ir_prefix_from_ir_value_match(match):
-    return nameless_values[get_idx_from_ir_value_match(match)].ir_prefix
+    idx = get_idx_from_ir_value_match(match)
+    if nameless_values[idx].ir_prefix and match.group(0).strip().startswith(nameless_values[idx].ir_prefix):
+        return nameless_values[idx].ir_prefix, nameless_values[idx].check_prefix
+    return nameless_values[idx].global_ir_prefix, nameless_values[idx].check_prefix
+
+def get_check_key_from_ir_value_match(match):
+    idx = get_idx_from_ir_value_match(match)
+    return nameless_values[idx].check_key
+
+# Return the IR regexp we use for this kind or IR value, e.g., [\w.-]+? for locals,
+# see also get_idx_from_ir_value_match
+def get_ir_prefix_from_ir_value_re_match(match):
+    # for backwards compatibility we check locals with '.*'
+    if is_local_def_ir_value_match(match):
+        return '.*'
+    idx = get_idx_from_ir_value_match(match)
+    if nameless_values[idx].ir_prefix and match.group(0).strip().startswith(nameless_values[idx].ir_prefix):
+        return nameless_values[idx].ir_regexp
+    return nameless_values[idx].global_ir_prefix_regexp
 
 # Return true if this kind or IR value is "local", basically if it matches '%{{.*}}'.
-def is_local_ir_value_match(match):
+def is_local_def_ir_value_match(match):
     return nameless_values[get_idx_from_ir_value_match(match)].ir_prefix == '%'
 
+# Return true if this kind or IR value is "local", basically if it matches '%{{.*}}'.
+def is_global_scope_ir_value_match(match):
+    return nameless_values[get_idx_from_ir_value_match(match)].global_ir_prefix is not None
+
 # Create a FileCheck variable name based on an IR name.
-def get_value_name(var, match):
+def get_value_name(var, check_prefix):
+  var = var.replace('!', '')
   if var.isdigit():
-    var = get_nameless_check_prefix_from_ir_value_match(match) + var
+    var = check_prefix + var
   var = var.replace('.', '_')
   var = var.replace('-', '_')
   return var.upper()
 
 # Create a FileCheck variable from regex.
 def get_value_definition(var, match):
-  return '[[' + get_value_name(var, match) + ':' + get_ir_prefix_from_ir_value_match(match) + '.*]]'
+  # for backwards compatibility we check locals with '.*'
+  if is_local_def_ir_value_match(match):
+    return '[[' + get_value_name(var, get_nameless_check_prefix_from_ir_value_match(match)) + ':' + \
+            get_ir_prefix_from_ir_value_match(match)[0] + get_ir_prefix_from_ir_value_re_match(match) + ']]'
+  prefix = get_ir_prefix_from_ir_value_match(match)[0]
+  return prefix + '[[' + get_value_name(var, get_nameless_check_prefix_from_ir_value_match(match)) + ':' + get_ir_prefix_from_ir_value_re_match(match) + ']]'
 
 # Use a FileCheck variable.
-def get_value_use(var, match):
-  return '[[' + get_value_name(var, match) + ']]'
+def get_value_use(var, match, check_prefix):
+  if is_local_def_ir_value_match(match):
+    return '[[' + get_value_name(var, check_prefix) + ']]'
+  prefix = get_ir_prefix_from_ir_value_match(match)[0]
+  return prefix + '[[' + get_value_name(var, check_prefix) + ']]'
 
 # Replace IR value defs and uses with FileCheck variables.
 def generalize_check_lines(lines, is_analyze, vars_seen, global_vars_seen):
@@ -438,18 +515,22 @@ def generalize_check_lines(lines, is_analyze, vars_seen, global_vars_seen):
   # a line. We transform variables we haven't seen
   # into defs, and variables we have seen into uses.
   def transform_line_vars(match):
-    pre = get_ir_prefix_from_ir_value_match(match)
+    pre, check = get_ir_prefix_from_ir_value_match(match)
     var = get_name_from_ir_value_match(match)
     for nameless_value in nameless_values:
-        if re.match(r'^' + nameless_value.check_prefix + r'[0-9]+?$', var, re.IGNORECASE):
+        if nameless_value.check_prefix and re.match(r'^' + nameless_value.check_prefix + r'[0-9]+?$', var, re.IGNORECASE):
             warn("Change IR value name '%s' to prevent possible conflict with scripted FileCheck name." % (var,))
-    if (pre, var) in vars_seen or (pre, var) in global_vars_seen:
-      rv = get_value_use(var, match)
+    key = (var, get_check_key_from_ir_value_match(match))
+    is_local_def = is_local_def_ir_value_match(match)
+    if is_local_def and key in vars_seen:
+      rv = get_value_use(var, match, get_nameless_check_prefix_from_ir_value_match(match))
+    elif not is_local_def and key in global_vars_seen:
+      rv = get_value_use(var, match, global_vars_seen[key])
     else:
-      if is_local_ir_value_match(match):
-         vars_seen.add((pre, var))
+      if is_local_def:
+         vars_seen.add(key)
       else:
-         global_vars_seen.add((pre, var))
+         global_vars_seen[key] = get_nameless_check_prefix_from_ir_value_match(match)
       rv = get_value_definition(var, match)
     # re.sub replaces the entire regex match
     # with whatever you return, so we have
@@ -490,8 +571,13 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
 
   # prefix_exclusions is constructed, we can now emit the output
   for p in prefix_list:
+    global_vars_seen = {}
     checkprefixes = p[0]
     for checkprefix in checkprefixes:
+      if checkprefix in global_vars_seen_dict:
+        global_vars_seen.update(global_vars_seen_dict[checkprefix])
+      else:
+        global_vars_seen_dict[checkprefix] = {}
       if checkprefix in printed_prefixes:
         break
 
@@ -510,8 +596,9 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
           output_lines.append(comment_marker)
 
       if checkprefix not in global_vars_seen_dict:
-          global_vars_seen_dict[checkprefix] = set()
-      global_vars_seen = global_vars_seen_dict[checkprefix]
+          global_vars_seen_dict[checkprefix] = {}
+
+      global_vars_seen_before = [key for key in global_vars_seen.keys()]
 
       vars_seen = set()
       printed_prefixes.append(checkprefix)
@@ -574,6 +661,11 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
       # Add space between 
diff erent check prefixes and also before the first
       # line of code in the test function.
       output_lines.append(comment_marker)
+
+      # Remembe new global variables we have not seen before
+      for key in global_vars_seen:
+          if key not in global_vars_seen_before:
+              global_vars_seen_dict[checkprefix][key] = global_vars_seen[key]
       break
 
 def add_ir_checks(output_lines, comment_marker, prefix_list, func_dict,
@@ -590,6 +682,75 @@ def add_analyze_checks(output_lines, comment_marker, prefix_list, func_dict, fun
   add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
              check_label_format, False, True, global_vars_seen_dict)
 
+def build_global_values_dictionary(glob_val_dict, raw_tool_output, prefixes):
+  for nameless_value in nameless_values:
+    if nameless_value.global_ir_prefix is None:
+      continue
+
+    lhs_re_str = nameless_value.global_ir_prefix + nameless_value.global_ir_prefix_regexp
+    rhs_re_str = nameless_value.global_ir_rhs_regexp
+
+    global_ir_value_re_str = r'^' + lhs_re_str + r'\s=\s' + rhs_re_str + r'$'
+    global_ir_value_re = re.compile(global_ir_value_re_str, flags=(re.M))
+    lines = []
+    for m in global_ir_value_re.finditer(raw_tool_output):
+        lines.append(m.group(0))
+
+    for prefix in prefixes:
+      if glob_val_dict[prefix] is None:
+        continue
+      if nameless_value.check_prefix in glob_val_dict[prefix]:
+        if lines == glob_val_dict[prefix][nameless_value.check_prefix]:
+          continue
+        if prefix == prefixes[-1]:
+          warn('Found conflicting asm under the same prefix: %r!' % (prefix,))
+        else:
+          glob_val_dict[prefix][nameless_value.check_prefix] = None
+          continue
+      glob_val_dict[prefix][nameless_value.check_prefix] = lines
+
+def add_global_checks(glob_val_dict, comment_marker, prefix_list, output_lines, global_vars_seen_dict, is_analyze, is_before_functions):
+  printed_prefixes = set()
+  for nameless_value in nameless_values:
+    if nameless_value.global_ir_prefix is None:
+        continue
+    if nameless_value.is_before_functions != is_before_functions:
+        continue
+    for p in prefix_list:
+      global_vars_seen = {}
+      checkprefixes = p[0]
+      for checkprefix in checkprefixes:
+        if checkprefix in global_vars_seen_dict:
+            global_vars_seen.update(global_vars_seen_dict[checkprefix])
+        else:
+            global_vars_seen_dict[checkprefix] = {}
+        if (checkprefix, nameless_value.check_prefix) in printed_prefixes:
+          break
+        if not glob_val_dict[checkprefix]:
+          continue
+        if nameless_value.check_prefix not in glob_val_dict[checkprefix]:
+          continue
+        if not glob_val_dict[checkprefix][nameless_value.check_prefix]:
+          continue
+
+        output_lines.append(SEPARATOR)
+
+        global_vars_seen_before = [key for key in global_vars_seen.keys()]
+        for line in glob_val_dict[checkprefix][nameless_value.check_prefix]:
+          tmp = generalize_check_lines([line], is_analyze, set(), global_vars_seen)
+          check_line = '%s %s: %s' % (comment_marker, checkprefix, tmp[0])
+          output_lines.append(check_line)
+        printed_prefixes.add((checkprefix, nameless_value.check_prefix))
+
+        # Remembe new global variables we have not seen before
+        for key in global_vars_seen:
+            if key not in global_vars_seen_before:
+                global_vars_seen_dict[checkprefix][key] = global_vars_seen[key]
+        break
+
+  if printed_prefixes:
+      output_lines.append(SEPARATOR)
+
 
 def check_prefix(prefix):
   if not PREFIX_RE.match(prefix):
@@ -642,8 +803,9 @@ def get_autogennote_suffix(parser, args):
 def check_for_command(line, parser, args, argv, argparse_callback):
     cmd_m = UTC_ARGS_CMD.match(line)
     if cmd_m:
-        cmd = cmd_m.group('cmd').strip().split(' ')
-        argv = argv + cmd
+        for option in cmd_m.group('cmd').strip().split(' '):
+            if option:
+                argv.append(option)
         args = parser.parse_args(filter(lambda arg: arg not in args.tests, argv))
         if argparse_callback is not None:
           argparse_callback(args)
@@ -678,6 +840,8 @@ def dump_input_lines(output_lines, test_info, prefix_set, comment_string):
     args = input_line_info.args
     if line.strip() == comment_string:
       continue
+    if line.strip() == SEPARATOR:
+      continue
     if line.lstrip().startswith(comment_string):
       m = CHECK_RE.match(line)
       if m and m.group(1) in prefix_set:

diff  --git a/llvm/utils/update_test_checks.py b/llvm/utils/update_test_checks.py
index 457b61d7f6bd..4a55ac6b7394 100755
--- a/llvm/utils/update_test_checks.py
+++ b/llvm/utils/update_test_checks.py
@@ -54,6 +54,8 @@ def main():
                       help='Remove attribute annotations (#0) from the end of check line')
   parser.add_argument('--check-attributes', action='store_true',
                       help='Check "Function Attributes" for functions')
+  parser.add_argument('--check-globals', action='store_true',
+                      help='Check global entries (global variables, metadata, attribute sets, ...) for functions')
   parser.add_argument('tests', nargs='+')
   initial_args = common.parse_commandline_args(parser)
 
@@ -111,7 +113,7 @@ def main():
       common.debug('Extracted opt cmd: ' + opt_basename + ' ' + opt_args)
       common.debug('Extracted FileCheck prefixes: ' + str(prefixes))
 
-      raw_tool_output = common.invoke_tool(ti.args.opt_binary, opt_args, 
+      raw_tool_output = common.invoke_tool(ti.args.opt_binary, opt_args,
                                            ti.path)
       builder.process_run_line(common.OPT_FUNCTION_RE, common.scrub_body,
               raw_tool_output, prefixes)
@@ -119,6 +121,7 @@ def main():
     func_dict = builder.finish_and_get_func_dict()
     is_in_function = False
     is_in_function_start = False
+    has_checked_pre_function_globals = False
     prefix_set = set([prefix for prefixes, _ in prefix_list for prefix in prefixes])
     common.debug('Rewriting FileCheck prefixes:', str(prefix_set))
     output_lines = []
@@ -138,13 +141,17 @@ def main():
       # out all the source lines.
       common.dump_input_lines(output_lines, ti, prefix_set, ';')
 
+      args = ti.args
+      if args.check_globals:
+          common.add_global_checks(builder.global_var_dict(), ';', prefix_list, output_lines, global_vars_seen_dict, args.preserve_names, True)
+
       # Now generate all the checks.
       common.add_checks_at_end(output_lines, prefix_list, builder.func_order(),
                                ';', lambda my_output_lines, prefixes, func:
                                common.add_ir_checks(my_output_lines, ';',
                                                     prefixes,
                                                     func_dict, func, False,
-                                                    ti.args.function_signature,
+                                                    args.function_signature,
                                                     global_vars_seen_dict))
     else:
       # "Normal" mode.
@@ -166,20 +173,23 @@ def main():
                                global_vars_seen_dict)
           is_in_function_start = False
 
-        if is_in_function:
-          if common.should_add_line_to_output(input_line, prefix_set):
+        m = common.IR_FUNCTION_RE.match(input_line)
+        if m and not has_checked_pre_function_globals:
+            if args.check_globals:
+                common.add_global_checks(builder.global_var_dict(), ';', prefix_list, output_lines, global_vars_seen_dict, args.preserve_names, True)
+            has_checked_pre_function_globals = True
+
+        if common.should_add_line_to_output(input_line, prefix_set, not is_in_function):
             # This input line of the function body will go as-is into the output.
             # Except make leading whitespace uniform: 2 spaces.
             input_line = common.SCRUB_LEADING_WHITESPACE_RE.sub(r'  ', input_line)
             output_lines.append(input_line)
-          else:
-            continue
-          if input_line.strip() == '}':
-            is_in_function = False
-          continue
+            if input_line.strip() == '}':
+                 is_in_function = False
+                 continue
 
-        # If it's outside a function, it just gets copied to the output.
-        output_lines.append(input_line)
+        if is_in_function:
+           continue
 
         m = common.IR_FUNCTION_RE.match(input_line)
         if not m:
@@ -190,6 +200,8 @@ def main():
           continue
         is_in_function = is_in_function_start = True
 
+    if args.check_globals:
+        common.add_global_checks(builder.global_var_dict(), ';', prefix_list, output_lines, global_vars_seen_dict, args.preserve_names, False)
     common.debug('Writing %d lines to %s...' % (len(output_lines), ti.path))
 
     with open(ti.path, 'wb') as f:


        


More information about the cfe-commits mailing list