[NewPM][ASan] Make ASan tests work under NPM
Under NPM, the asan-globals-md analysis is required but cannot be run
within the asan function pass due to module analyses not being able to
run from a function pass. So this pins all tests using "-asan" to the
legacy PM and adds a corresponding RUN line with
-passes='require<asan-globals-md>,function(asan)'.
Now all tests in Instrumentation/AddressSanitizer pass when
-enable-new-pm is by default on.
Tests were automatically converted using the following python script and
failures were manually fixed up.
import sys
for i in sys.argv:
with open(i, 'r') as f:
s = f.read()
with open(i, 'w') as f:
for l in s.splitlines():
if "RUN:" in l and ' -asan -asan-module ' in l and '\\' not in l:
f.write(l.replace(' -asan -asan-module ', ' -asan -asan-module -enable-new-pm=0 '))
f.write('\n')
f.write(l.replace(' -asan -asan-module ', " -passes='require<asan-globals-md>,function(asan),module(asan-module)' "))
f.write('\n')
elif "RUN:" in l and ' -asan ' in l and '\\' not in l:
f.write(l.replace(' -asan ', ' -asan -enable-new-pm=0 '))
f.write('\n')
f.write(l.replace(' -asan ', " -passes='require<asan-globals-md>,function(asan)' "))
f.write('\n')
else:
f.write(l)
f.write('\n')
See https://bugs.llvm.org/show_bug.cgi?id=46611.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D83921
2020-07-18 08:49:46 +08:00
; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=0 -S | FileCheck %s
; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=0 -S | FileCheck %s
2012-12-12 22:31:53 +08:00
2020-09-27 06:04:31 +08:00
; Checks that llvm.dbg.declare instructions are updated
2012-12-12 22:31:53 +08:00
; accordingly as we merge allocas.
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
2020-09-27 06:04:31 +08:00
@G = global [ 32 x i8 ] zeroinitializer , align 32 , !dbg !0 , !type !6
; CHECK: @G = global { [32 x i8], [32 x i8] } zeroinitializer{{(, comdat)?}}, align 32, !dbg !0, !type [[TYPE:![0-9]+]]
define i32 @_Z3zzzi ( i32 %p ) nounwind uwtable sanitize_address !dbg !12 {
2012-12-12 22:31:53 +08:00
entry:
%p.addr = alloca i32 , align 4
%r = alloca i32 , align 4
2015-02-27 11:12:36 +08:00
store volatile i32 %p , i32 * %p.addr , align 4
2020-09-27 06:04:31 +08:00
call void @llvm.dbg.declare ( metadata i32 * %p.addr , metadata !17 , metadata !DIExpression ( ) ) , !dbg !18
call void @llvm.dbg.declare ( metadata i32 * %r , metadata !19 , metadata !DIExpression ( ) ) , !dbg !21
%0 = load i32 , i32 * %p.addr , align 4 , !dbg !21
%add = add nsw i32 %0 , 1 , !dbg !21
store volatile i32 %add , i32 * %r , align 4 , !dbg !21
%1 = load i32 , i32 * %r , align 4 , !dbg !22
ret i32 %1 , !dbg !22
2012-12-12 22:31:53 +08:00
}
; CHECK: define i32 @_Z3zzzi
2020-02-11 07:37:56 +08:00
; CHECK: [[MyAlloca:%.*]] = alloca i8, i64 64
[AddressSanitizer] Ensure only AllocaInst is passed to dbg.declare
Various parts of the LLVM code generator assume that the address
argument of a dbg.declare is not a `ptrtoint`-of-alloca. ASan breaks
this assumption, and this results in local variables sometimes being
unavailable at -O0.
GlobalISel, SelectionDAG, and FastISel all do not appear to expect
dbg.declares to have a `ptrtoint` as an operand. This means that they do
not place entry block allocas in the usual side table reserved for local
variables available in the whole function scope. This isn't always a
problem, as LLVM can try to lower the dbg.declare to a DBG_VALUE, but
those DBG_VALUEs can get dropped for all the usual reasons DBG_VALUEs
get dropped. In the ObjC test case I'm looking at, the cause happens to
be that `replaceDbgDeclare` has hoisted dbg.declares into the entry
block, causing LiveDebugValues to "kill" the DBG_VALUEs because the
lexical dominance check fails.
To address this, I propose:
1) Have ASan (always) pass an alloca to dbg.declares (this patch). This
is a narrow bugfix for -O0 debugging.
2) Make replaceDbgDeclare not move dbg.declares around. This should be a
generic improvement for optimized debug info, as it would prevent the
lexical dominance check in LiveDebugValues from killing as many
variables.
This means reverting llvm/r227544, which fixed an assertion failure
(llvm.org/PR22386) but no longer seems to be necessary. I was able to
complete a stage2 build with the revert in place.
rdar://54688991
Differential Revision: https://reviews.llvm.org/D74369
2020-02-11 08:22:27 +08:00
; Note: these dbg.declares used to contain `ptrtoint` operands. The instruction
; selector would then decline to put the variable in the MachineFunction side
; table. Check that the dbg.declares have `alloca` operands.
; CHECK: call void @llvm.dbg.declare(metadata i8* [[MyAlloca]], metadata ![[ARG_ID:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 32))
; CHECK: call void @llvm.dbg.declare(metadata i8* [[MyAlloca]], metadata ![[VAR_ID:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 48))
2012-12-12 22:31:53 +08:00
Move the complex address expression out of DIVariable and into an extra
argument of the llvm.dbg.declare/llvm.dbg.value intrinsics.
Previously, DIVariable was a variable-length field that has an optional
reference to a Metadata array consisting of a variable number of
complex address expressions. In the case of OpPiece expressions this is
wasting a lot of storage in IR, because when an aggregate type is, e.g.,
SROA'd into all of its n individual members, the IR will contain n copies
of the DIVariable, all alike, only differing in the complex address
reference at the end.
By making the complex address into an extra argument of the
dbg.value/dbg.declare intrinsics, all of the pieces can reference the
same variable and the complex address expressions can be uniqued across
the CU, too.
Down the road, this will allow us to move other flags, such as
"indirection" out of the DIVariable, too.
The new intrinsics look like this:
declare void @llvm.dbg.declare(metadata %storage, metadata %var, metadata %expr)
declare void @llvm.dbg.value(metadata %storage, i64 %offset, metadata %var, metadata %expr)
This patch adds a new LLVM-local tag to DIExpressions, so we can detect
and pretty-print DIExpression metadata nodes.
What this patch doesn't do:
This patch does not touch the "Indirect" field in DIVariable; but moving
that into the expression would be a natural next step.
http://reviews.llvm.org/D4919
rdar://problem/17994491
Thanks to dblaikie and dexonsmith for reviewing this patch!
Note: I accidentally committed a bogus older version of this patch previously.
llvm-svn: 218787
2014-10-02 02:55:02 +08:00
declare void @llvm.dbg.declare ( metadata , metadata , metadata ) nounwind readnone
2012-12-12 22:31:53 +08:00
2020-09-27 06:04:31 +08:00
!llvm.dbg.cu = ! { !7 }
!llvm.module.flags = ! { !24 }
!0 = !DIGlobalVariableExpression ( var: !1 , expr: !DIExpression ( ) )
!1 = distinct !DIGlobalVariable ( name: "G" , type: !2 , isLocal: false , isDefinition: true )
!2 = !DICompositeType ( tag: D W _ T A G _ a r r a y _ type , baseType: !3 , size: 256 , elements: !4 )
!3 = !DIBasicType ( name: "unsigned char" , size: 8 , encoding: D W _ A T E _ u n s i g n e d _ c h a r )
!4 = ! { !5 }
!5 = !DISubrange ( count: 32 )
!6 = ! { i64 0 , !"G" }
; CHECK: [[TYPE]] = !{i64 0, !"G"}
2012-12-12 22:31:53 +08:00
2020-09-27 06:04:31 +08:00
!7 = distinct !DICompileUnit ( language: D W _ L A N G _ C _ p l u s _ p l u s , producer: "clang version 3.3 (trunk 169314)" , isOptimized: true , emissionKind: F u l l D e b u g , file: !23 , enums: !8 , retainedTypes: !8 , globals: !8 )
!8 = ! { }
!12 = distinct !DISubprogram ( name: "zzz" , linkageName: "_Z3zzzi" , line: 1 , isLocal: false , isDefinition: true , virtualIndex: 6 , flags: D I F l a g P r o t o t y p e d , isOptimized: false , unit: !7 , scopeLine: 1 , file: !23 , scope: !13 , type: !14 , retainedNodes: !8 )
!13 = !DIFile ( filename: "a.cc" , directory: "/usr/local/google/llvm_cmake_clang/tmp/debuginfo" )
!14 = !DISubroutineType ( types: !15 )
!15 = ! { !16 , !16 }
!16 = !DIBasicType ( tag: D W _ T A G _ b a s e _ type , name: "int" , size: 32 , align: 32 , encoding: D W _ A T E _ s i g n e d )
!17 = !DILocalVariable ( name: "p" , line: 1 , arg: 1 , scope: !12 , file: !13 , type: !16 )
!18 = !DILocation ( line: 1 , scope: !12 )
!19 = !DILocalVariable ( name: "r" , line: 2 , scope: !20 , file: !13 , type: !16 )
2012-12-12 22:31:53 +08:00
; Verify that debug descriptors for argument and local variable will be replaced
; with descriptors that end with OpDeref (encoded as 2).
2015-08-01 02:58:39 +08:00
; CHECK: ![[ARG_ID]] = !DILocalVariable(name: "p", arg: 1,{{.*}} line: 1
; CHECK: ![[VAR_ID]] = !DILocalVariable(name: "r",{{.*}} line: 2
2012-12-12 22:31:53 +08:00
; Verify that there are no more variable descriptors.
2015-04-30 00:38:44 +08:00
; CHECK-NOT: !DILocalVariable(tag: DW_TAG_arg_variable
; CHECK-NOT: !DILocalVariable(tag: DW_TAG_auto_variable
2012-12-12 22:31:53 +08:00
2020-09-27 06:04:31 +08:00
!20 = distinct !DILexicalBlock ( line: 1 , column: 0 , file: !23 , scope: !12 )
!21 = !DILocation ( line: 2 , scope: !20 )
!22 = !DILocation ( line: 3 , scope: !20 )
!23 = !DIFile ( filename: "a.cc" , directory: "/usr/local/google/llvm_cmake_clang/tmp/debuginfo" )
!24 = ! { i32 1 , !"Debug Info Version" , i32 3 }