1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[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
This commit is contained in:
Johannes Doerfert 2021-01-14 21:13:23 -06:00
parent 6c444365cb
commit 6e9991eb47
15 changed files with 816 additions and 161 deletions

View File

@ -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]]

View File

@ -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]]

View File

@ -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"
@G = external dso_local global i32, align 4
define void @foo(i32) {
%2 = icmp eq i32 %0, 0
tail call void @_Z10sideeffectv()

View File

@ -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"
@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

View File

@ -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"
@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 }
;.

View File

@ -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"
@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

View File

@ -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"
@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 }
;.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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@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@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@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@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)
;.

View File

@ -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

View File

@ -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

View File

@ -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 @@ SCRUB_LOOP_COMMENT_RE = re.compile(
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 @@ class function_body(object):
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 @@ class FunctionTestBuilder:
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 @@ class FunctionTestBuilder:
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 @@ class FunctionTestBuilder:
# 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 @@ SCRUB_IR_COMMENT_RE = re.compile(r'\s*;.*')
# 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 different "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 @@ IR_VALUE_RE = re.compile(IR_VALUE_REGEXP_PREFIX + r'(' + IR_VALUE_REGEXP_STRING
# 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 different 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:

View File

@ -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: