[clang] 97ce7fd - [UpdateTestChecks] Match unnamed values like "@[0-9]+" and "![0-9]+"

Johannes Doerfert via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 11 23:06:19 PDT 2020


Author: Johannes Doerfert
Date: 2020-08-12T01:04:16-05:00
New Revision: 97ce7fd89fcc92d84c1938108388f735d55d372c

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

LOG: [UpdateTestChecks] Match unnamed values like "@[0-9]+" and "![0-9]+"

With this patch we will match most *uses* of "temporary" named things in
the IR via regular expressions, not their name at creation time. The new
"values" we match are:
  - "unnamed" globals: `@[0-9]+`
  - debug metadata: `!dbg ![0-9]+`
  - loop metadata: `!loop ![0-9]+`
  - tbaa metadata: `!tbaa ![0-9]+`
  - range metadata: `!range ![0-9]+`
  - generic metadata: `metadata ![0-9]+`
  - attributes groups: `#[0-9]`

We still don't match the declarations but that can be done later. This
patch can introduce churn when existing check lines contain the old
hardcoded versions of the above "values". We can add a flag to opt-out,
or opt-in, if necessary.

Reviewed By: arichardson, MaskRay

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

Added: 
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll
    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/various_ir_values.test

Modified: 
    clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.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/scrub_attrs.ll.plain.expected
    llvm/utils/UpdateTestChecks/asm.py
    llvm/utils/UpdateTestChecks/common.py
    llvm/utils/update_cc_test_checks.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 48ee67a7165a..8095b10d7877 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* [[THIS1]]) #2
+// CHECK-NEXT:    call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR2:#.*]]
 // 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* [[F]], i32 1)
 // CHECK-NEXT:    [[CALL:%.*]] = call i32 @_ZNK3Foo23function_defined_inlineEi(%class.Foo* [[F]], i32 2)
 // CHECK-NEXT:    [[CALL1:%.*]] = call i32 @_ZNK3Foo28function_defined_out_of_lineEi(%class.Foo* [[F]], i32 3)
-// CHECK-NEXT:    call void @_ZN3FooD1Ev(%class.Foo* [[F]]) #2
+// CHECK-NEXT:    call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR2]]
 // CHECK-NEXT:    ret i32 0
 //
 int main() {

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 e76cf074bdb7..313bd5bcef7c 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:%.*]]) #0
+// CHECK-SAME: (i64 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0:#.*]]
 // 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:%.*]]) #0
+// 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 be84e7824377..6fa31342e9a2 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:%.*]]) #0
+; IS__TUNIT____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) [[ATTR0:#.*]]
 ; 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:%.*]]) #0
+; IS__CGSCC____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) [[ATTR0:#.*]]
 ; 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 af95eefbce2d..e749f3152a65 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:%.*]]) #0
+; CHECK-SAME: (%struct.ST* nofree readnone [[S:%.*]]) [[ATTR0:#.*]]
 ; 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/scrub_attrs.ll.plain.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.plain.expected
index 525e57432fb7..11934b86c0bb 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() #0
+; CHECK-NEXT:    call void @foo() [[ATTR0:#.*]]
 ; CHECK-NEXT:    ret void
 ;
   call void @foo() readnone

diff  --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll
new file mode 100644
index 000000000000..d99391cb2941
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll
@@ -0,0 +1,173 @@
+; 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 {
+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 {
+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)

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
new file mode 100644
index 000000000000..b33ea0488123
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.expected
@@ -0,0 +1,246 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; 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: @foo(
+; 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:       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:       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:    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:       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:       for.end:
+; CHECK-NEXT:    ret void, [[DBG38:!dbg !.*]]
+;
+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: @bar(
+; 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:       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:       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:    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:       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:       for.end:
+; CHECK-NEXT:    ret void, [[DBG60:!dbg !.*]]
+;
+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)

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
new file mode 100644
index 000000000000..3d4e56d2ad1f
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.expected
@@ -0,0 +1,248 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
+; 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:#.*]] [[DBG7:!dbg !.*]]
+; 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:       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:       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:    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:       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:       for.end:
+; CHECK-NEXT:    ret void, [[DBG38:!dbg !.*]]
+;
+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]] [[DBG39:!dbg !.*]]
+; 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:       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:       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:    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:       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:       for.end:
+; CHECK-NEXT:    ret void, [[DBG60:!dbg !.*]]
+;
+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)

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
new file mode 100644
index 000000000000..19b63450f5ca
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/various_ir_values.test
@@ -0,0 +1,16 @@
+## Basic test checking that update_test_checks.py works correctly on various "IR value" kinds
+# RUN: cp -f %S/Inputs/various_ir_values.ll %t.ll && %update_test_checks %t.ll
+# RUN: 
diff  -u %t.ll %S/Inputs/various_ir_values.ll.expected
+## Check that running the script again does not change the result:
+# RUN: %update_test_checks %t.ll
+# RUN: 
diff  -u %t.ll %S/Inputs/various_ir_values.ll.expected
+## Also try the --function-signature flag
+# RUN: %update_test_checks %t.ll --function-signature
+# RUN: 
diff  -u %t.ll %S/Inputs/various_ir_values.ll.funcsig.expected
+## Verify that running without the --function-signature flag does not removes
+## the -SAME: lines since the generated file will have --function-signature in
+## an UTC_ARGS: comment in the first line (from the invocation above) which is
+## 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
+

diff  --git a/llvm/utils/UpdateTestChecks/asm.py b/llvm/utils/UpdateTestChecks/asm.py
index cfcc8deb7c8c..84db0145e947 100644
--- a/llvm/utils/UpdateTestChecks/asm.py
+++ b/llvm/utils/UpdateTestChecks/asm.py
@@ -371,4 +371,5 @@ def build_function_body_dictionary_for_triple(args, raw_tool_output, triple, pre
 def add_asm_checks(output_lines, comment_marker, prefix_list, func_dict, func_name):
   # Label format is based on ASM string.
   check_label_format = '{} %s-LABEL: %s%s:'.format(comment_marker)
-  common.add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, True, False)
+  global_vars_seen_dict = {}
+  common.add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, True, False, global_vars_seen_dict)

diff  --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 35b7ba648d36..5bc478a1e84b 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -229,12 +229,12 @@ 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(2))
-        return match.group(1) + match.group(3)
+        arg_names.add(match.group(3))
+        return match.group(1) + match.group(match.lastindex)
     def repl_arg_names(match):
-        if match.group(2) in arg_names:
-            return match.group(1) + match.group(3)
-        return match.group(1) + match.group(2) + match.group(3)
+        if match.group(3) 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:
       return False
     ans0 = IR_VALUE_RE.sub(drop_arg_names, self.args_and_sig)
@@ -297,49 +297,111 @@ def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_too
 
 SCRUB_IR_COMMENT_RE = re.compile(r'\s*;.*')
 
-# Match things that look at identifiers, but only if they are followed by
-# spaces, commas, paren, or end of the string
-IR_VALUE_RE = re.compile(r'(\s+)%([\w.-]+?)([,\s\(\)]|\Z)')
-
-NAMELESS_PREFIX = "TMP"
+# TODO: We should also derive check lines for global, debug, loop declarations, etc..
+
+class NamelessValue:
+    def __init__(self, check_prefix, ir_prefix, ir_regexp):
+        self.check_prefix = check_prefix
+        self.ir_prefix = ir_prefix
+        self.ir_regexp = ir_regexp
+
+# 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]+?'),
+]
+
+# 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_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')'
+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)
+
+# The entire match is group 0, the prefix has one group (=1), the entire
+# IR_VALUE_REGEXP_STRING is one group (=2), and then the nameless values start.
+first_nameless_group_in_ir_value_match = 3
+
+# 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):
+    for i in range(first_nameless_group_in_ir_value_match, match.lastindex):
+        if match.group(i) is not None:
+            return i - first_nameless_group_in_ir_value_match
+    error("Unable to identify the kind of IR value from the match!")
+    return 0;
+
+# See get_idx_from_ir_value_match
+def get_name_from_ir_value_match(match):
+    return match.group(get_idx_from_ir_value_match(match) + first_nameless_group_in_ir_value_match)
+
+# Return the nameless prefix we use for this kind or IR value, see also
+# get_idx_from_ir_value_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,
+# 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
+
+# Return true if this kind or IR value is "local", basically if it matches '%{{.*}}'.
+def is_local_ir_value_match(match):
+    return nameless_values[get_idx_from_ir_value_match(match)].ir_prefix == '%'
 
 # Create a FileCheck variable name based on an IR name.
-def get_value_name(var):
+def get_value_name(var, match):
   if var.isdigit():
-    var = NAMELESS_PREFIX + var
+    var = get_nameless_check_prefix_from_ir_value_match(match) + var
   var = var.replace('.', '_')
   var = var.replace('-', '_')
   return var.upper()
 
-
 # Create a FileCheck variable from regex.
-def get_value_definition(var):
-  return '[[' + get_value_name(var) + ':%.*]]'
-
+def get_value_definition(var, match):
+  return '[[' + get_value_name(var, match) + ':' + get_ir_prefix_from_ir_value_match(match) + '.*]]'
 
 # Use a FileCheck variable.
-def get_value_use(var):
-  return '[[' + get_value_name(var) + ']]'
+def get_value_use(var, match):
+  return '[[' + get_value_name(var, match) + ']]'
 
 # Replace IR value defs and uses with FileCheck variables.
-def genericize_check_lines(lines, is_analyze, vars_seen):
+def genericize_check_lines(lines, is_analyze, vars_seen, global_vars_seen):
   # This gets called for each match that occurs in
   # a line. We transform variables we haven't seen
   # into defs, and variables we have seen into uses.
   def transform_line_vars(match):
-    var = match.group(2)
-    if NAMELESS_PREFIX.lower() in var.lower():
-      warn("Change IR value name '%s' to prevent possible conflict with scripted FileCheck name." % (var,))
-    if var in vars_seen:
-      rv = get_value_use(var)
+    pre = get_ir_prefix_from_ir_value_match(match)
+    var = get_name_from_ir_value_match(match)
+    for nameless_value in nameless_values:
+        if re.fullmatch(nameless_value.ir_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)
     else:
-      vars_seen.add(var)
-      rv = get_value_definition(var)
+      if is_local_ir_value_match(match):
+         vars_seen.add((pre, var))
+      else:
+         global_vars_seen.add((pre, var))
+      rv = get_value_definition(var, match)
     # re.sub replaces the entire regex match
     # with whatever you return, so we have
     # to make sure to hand it back everything
     # including the commas and spaces.
-    return match.group(1) + rv + match.group(3)
+    return match.group(1) + rv + match.group(match.lastindex)
 
   lines_with_def = []
 
@@ -348,14 +410,18 @@ def transform_line_vars(match):
     line = line.replace('%.', '%dot')
     # Ignore any comments, since the check lines will too.
     scrubbed_line = SCRUB_IR_COMMENT_RE.sub(r'', line)
-    if is_analyze:
-      lines[i] = scrubbed_line
-    else:
-      lines[i] = IR_VALUE_RE.sub(transform_line_vars, scrubbed_line)
+    lines[i] = scrubbed_line
+    if not is_analyze:
+      # It can happen that two matches are back-to-back and for some reason sub
+      # will not replace both of them. For now we work around this by
+      # substituting until there is no more match.
+      changed = True
+      while changed:
+          (lines[i], changed) = IR_VALUE_RE.subn(transform_line_vars, lines[i], count=1)
   return lines
 
 
-def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, is_asm, is_analyze):
+def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, is_asm, is_analyze, global_vars_seen_dict):
   # prefix_exclusions are prefixes we cannot use to print the function because it doesn't exist in run lines that use these prefixes as well.
   prefix_exclusions = set()
   printed_prefixes = []
@@ -389,6 +455,10 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
         if len(printed_prefixes) != 0:
           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]
+
       vars_seen = set()
       printed_prefixes.append(checkprefix)
       attrs = str(func_dict[checkprefix][func_name].attrs)
@@ -396,7 +466,7 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
       if attrs:
         output_lines.append('%s %s: Function Attrs: %s' % (comment_marker, checkprefix, attrs))
       args_and_sig = str(func_dict[checkprefix][func_name].args_and_sig)
-      args_and_sig = genericize_check_lines([args_and_sig], is_analyze, vars_seen)[0]
+      args_and_sig = genericize_check_lines([args_and_sig], is_analyze, vars_seen, global_vars_seen)[0]
       if '[[' in args_and_sig:
         output_lines.append(check_label_format % (checkprefix, func_name, ''))
         output_lines.append('%s %s-SAME: %s' % (comment_marker, checkprefix, args_and_sig))
@@ -416,7 +486,7 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
 
       # For IR output, change all defs to FileCheck variables, so we're immune
       # to variable naming fashions.
-      func_body = genericize_check_lines(func_body, is_analyze, vars_seen)
+      func_body = genericize_check_lines(func_body, is_analyze, vars_seen, global_vars_seen)
 
       # This could be selectively enabled with an optional invocation argument.
       # Disabled for now: better to check everything. Be safe rather than sorry.
@@ -453,16 +523,18 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
       break
 
 def add_ir_checks(output_lines, comment_marker, prefix_list, func_dict,
-                  func_name, preserve_names, function_sig):
+                  func_name, preserve_names, function_sig, global_vars_seen_dict):
   # Label format is based on IR string.
   function_def_regex = 'define {{[^@]+}}' if function_sig else ''
   check_label_format = '{} %s-LABEL: {}@%s%s'.format(comment_marker, function_def_regex)
   add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
-             check_label_format, False, preserve_names)
+             check_label_format, False, preserve_names, global_vars_seen_dict)
 
 def add_analyze_checks(output_lines, comment_marker, prefix_list, func_dict, func_name):
   check_label_format = '{} %s-LABEL: \'%s%s\''.format(comment_marker)
-  add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, False, True)
+  global_vars_see_dict = {}
+  add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
+             check_label_format, False, True, global_vars_seen_dict)
 
 
 def check_prefix(prefix):

diff  --git a/llvm/utils/update_cc_test_checks.py b/llvm/utils/update_cc_test_checks.py
index ba8a68b8669f..e12be684016f 100755
--- a/llvm/utils/update_cc_test_checks.py
+++ b/llvm/utils/update_cc_test_checks.py
@@ -262,6 +262,7 @@ def main():
       for k, v in get_line2spell_and_mangled(ti.args, clang_args).items():
         line2spell_and_mangled_list[k].append(v)
 
+    global_vars_seen_dict = {}
     prefix_set = set([prefix for p in run_list for prefix in p[0]])
     output_lines = []
     for line_info in ti.iterlines(output_lines):
@@ -293,7 +294,7 @@ def main():
               output_lines.append('//')
             added.add(mangled)
             common.add_ir_checks(output_lines, '//', run_list, func_dict, mangled,
-                                 False, args.function_signature)
+                                 False, args.function_signature, global_vars_seen_dict)
             if line.rstrip('\n') == '//':
               include_line = False
 

diff  --git a/llvm/utils/update_test_checks.py b/llvm/utils/update_test_checks.py
index 660b109c323a..33fee8884675 100755
--- a/llvm/utils/update_test_checks.py
+++ b/llvm/utils/update_test_checks.py
@@ -101,6 +101,7 @@ def main():
       # now, we just ignore all but the last.
       prefix_list.append((check_prefixes, tool_cmd_args))
 
+    global_vars_seen_dict = {}
     func_dict = {}
     for prefixes, _ in prefix_list:
       for prefix in prefixes:
@@ -134,7 +135,8 @@ def main():
 
         # Print out the various check lines here.
         common.add_ir_checks(output_lines, ';', prefix_list, func_dict,
-                             func_name, args.preserve_names, args.function_signature)
+                             func_name, args.preserve_names, args.function_signature,
+                             global_vars_seen_dict)
         is_in_function_start = False
 
       if is_in_function:


        


More information about the cfe-commits mailing list