// REQUIRES: asserts
//
// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret --no-threads \
// RUN:    -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC %s
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret --no-threads --auth-traps-on-failure \
// RUN:    -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC %s
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all     --no-threads \
// RUN:    -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC,AUTH-ORACLES,PAUTH %s
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all     --no-threads --auth-traps-on-failure \
// RUN:    -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC,PAUTH %s

// Check the debug output generated by PAuth gadget scanner to make sure the
// that output is kept meaningful and to provide an overview of what happens
// inside the scanner.

        .globl  simple
        .type   simple,@function
simple:
        paciasp
        stp     x29, x30, [sp, #-0x10]!
        b       1f
1:
        autiza  x0
        blr     x0
        ldp     x29, x30, [sp], #0x10
        autiasp
        ret
        .size simple, .-simple

// CHECK-LABEL:Analyzing function simple, AllocatorId = 1
// CHECK-NEXT: Binary Function "simple"  {
// CHECK-NEXT:   Number      : 1
// CHECK-NEXT:   State       : CFG constructed
// ...
// CHECK:        BB Layout   : [[BB0:[0-9a-zA-Z.]+]], [[BB1:[0-9a-zA-Z.]+]]
// CHECK-NEXT: }
// CHECK-NEXT: [[BB0]] (3 instructions, align : 1)
// CHECK-NEXT:   Entry Point
// CHECK-NEXT:     00000000:   paciasp
// CHECK-NEXT:     00000004:   stp x29, x30, [sp, #-0x10]!
// CHECK-NEXT:     00000008:   b       [[BB1]]
// CHECK-NEXT:   Successors: [[BB1]]
// CHECK-EMPTY:
// CHECK-NEXT: [[BB1]] (5 instructions, align : 1)
// CHECK-NEXT:   Predecessors: [[BB0]]
// CHECK-NEXT:     0000000c:   autiza   x0
// CHECK-NEXT:     00000010:   blr      x0
// CHECK-NEXT:     00000014:   ldp     x29, x30, [sp], #0x10
// CHECK-NEXT:     00000018:   autiasp
// CHECK-NEXT:     0000001c:   ret
// CHECK-EMPTY:
// CHECK-NEXT: DWARF CFI Instructions:
// CHECK-NEXT:     <empty>
// CHECK-NEXT: End of Function "simple"
// CHECK-EMPTY:
// CHECK-NEXT: Running src register safety analysis...
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(   hint    #25, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(   stp     x29, x30, [sp, #-0x10]!, src-state<SafeToDerefRegs: , TrustedRegs:  , Insts: >)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs:  , Insts: >)
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(   b       [[BB1]], src-state<SafeToDerefRegs: , TrustedRegs:  , Insts: >)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs:  , Insts: >)
// CHECK-NEXT:   DataflowSrcSafetyAnalysis::Confluence(
// CHECK-NEXT:     State 1: src-state<empty>
// CHECK-NEXT:     State 2: src-state<SafeToDerefRegs: , TrustedRegs:  , Insts: >)
// CHECK-NEXT:     merged state: src-state<SafeToDerefRegs: , TrustedRegs:  , Insts: >
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   autiza  x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   blr     x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   ldp     x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   hint    #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   ret     x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:   DataflowSrcSafetyAnalysis::Confluence(
// NOFPAC-NEXT:     State 1: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
// NOFPAC-NEXT:     State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   autiza  x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   blr     x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   ldp     x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   hint    #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   ret     x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
// NOFPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   autiza  x0, src-state<SafeToDerefRegs: , TrustedRegs:  , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >)
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   blr     x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   ldp     x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   hint    #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   ret     x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// FPAC-NEXT:   DataflowSrcSafetyAnalysis::Confluence(
// FPAC-NEXT:     State 1: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
// FPAC-NEXT:     State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:     merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   autiza  x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >)
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   blr     x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   ldp     x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   hint    #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// FPAC-NEXT:   SrcSafetyAnalysis::ComputeNext(   ret     x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// FPAC-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: After src register safety analysis:
// CHECK-NEXT: Binary Function "simple"  {
// CHECK-NEXT:   Number      : 1
// CHECK-NEXT:   State       : CFG constructed
// ...
// CHECK:        BB Layout   : [[BB0]], [[BB1]]
// CHECK-NEXT: }
// CHECK-NEXT: [[BB0]] (3 instructions, align : 1)
// CHECK-NEXT:   Entry Point
// CHECK-NEXT:     00000000:   paciasp # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     00000004:   stp     x29, x30, [sp, #-0x10]! # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     00000008:   b       [[BB1]] # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:   Successors: [[BB1]]
// CHECK-EMPTY:
// CHECK-NEXT: [[BB1]] (5 instructions, align : 1)
// CHECK-NEXT:   Predecessors: [[BB0]]
// CHECK-NEXT:     0000000c:   autiza  x0 # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     00000010:   blr     x0 # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     00000014:   ldp     x29, x30, [sp], #0x10 # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     00000018:   autiasp # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     0000001c:   ret # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-EMPTY:
// CHECK-NEXT: DWARF CFI Instructions:
// CHECK-NEXT:     <empty>
// CHECK-NEXT: End of Function "simple"
// CHECK-EMPTY:
// PAUTH-NEXT:   Found sign inst:     00000000:        paciasp # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// PAUTH-NEXT:     Signed reg: LR
// PAUTH-NEXT:     TrustedRegs: LR W30 W30_HI{{[ \t]*$}}
// PAUTH-NEXT:   Found call inst:     00000000:        blr     x0 # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// PAUTH-NEXT:     Call destination reg: X0
// PAUTH-NEXT:     SafeToDerefRegs: W0 X0 W0_HI{{[ \t]*$}}
// CHECK-NEXT:   Found RET inst:     00000000:         ret # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     RetReg: LR
// CHECK-NEXT:     SafeToDerefRegs: LR W30 W30_HI{{[ \t]*$}}

        .globl  clobber
        .type   clobber,@function
clobber:
        mov     w30, #0
        ret
        .size clobber, .-clobber

// CHECK-LABEL:Analyzing function clobber, AllocatorId = 1
// ...
// CHECK:      Running src register safety analysis...
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(   mov     w30, #0x0, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: W30_HI , TrustedRegs: W30_HI , Insts: >)
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(   ret     x30, src-state<SafeToDerefRegs: W30_HI , TrustedRegs: W30_HI , Insts: >)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: W30_HI , TrustedRegs: W30_HI , Insts: >)
// CHECK-NEXT: After src register safety analysis:
// CHECK-NEXT: Binary Function "clobber"  {
// ...
// CHECK:      End of Function "clobber"

// The above output was printed after first run of analysis

// CHECK-EMPTY:
// CHECK-NEXT:   Found RET inst:     00000000:         ret # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     RetReg: LR
// CHECK-NEXT:     SafeToDerefRegs: W30_HI{{[ \t]*$}}
// CHECK-EMPTY:
// CHECK-NEXT: Running detailed src register safety analysis...
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(   mov     w30, #0x0, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: [0]()>)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: W30_HI , TrustedRegs: W30_HI , Insts: [0](0x{{[0-9a-f]+}})>)
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(   ret     x30, src-state<SafeToDerefRegs: W30_HI , TrustedRegs: W30_HI , Insts: [0](0x{{[0-9a-f]+}})>)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: W30_HI , TrustedRegs: W30_HI , Insts: [0](0x{{[0-9a-f]+}})>)
// CHECK-NEXT: After detailed src register safety analysis:
// CHECK-NEXT: Binary Function "clobber"  {
// ...
// CHECK:      End of Function "clobber"

// The analysis was re-computed with register tracking, as an issue was found in this function.
// Iterating over the reports and attaching clobbering info:

// CHECK-EMPTY:
// CHECK-NEXT:   Attaching clobbering info to:     00000000:         ret # DataflowSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: [0](0x{{[0-9a-f]+}})>

        .globl  nocfg
        .type   nocfg,@function
nocfg:
        adr     x0, 1f
        br      x0
1:
        ret
        .size nocfg, .-nocfg

// CHECK-LABEL:Analyzing function nocfg, AllocatorId = 1
// CHECK-NEXT: Binary Function "nocfg"  {
// CHECK-NEXT:   Number      : 3
// CHECK-NEXT:   State       : disassembled
// ...
// CHECK:        IsSimple    : 0
// CHECK-NEXT:   IsMultiEntry: 1
// CHECK-NEXT:   IsSplit     : 0
// CHECK-NEXT:   BB Count    : 0
// CHECK-NEXT:   Secondary Entry Points : __ENTRY_nocfg@0x[[ENTRY_ADDR:[0-9a-f]+]]
// CHECK-NEXT: }
// CHECK-NEXT: .{{[A-Za-z0-9]+}}:
// CHECK-NEXT:     00000000:   adr     x0, __ENTRY_nocfg@0x[[ENTRY_ADDR]]
// CHECK-NEXT:     00000004:   br      x0 # UNKNOWN CONTROL FLOW # Offset: 4
// CHECK-NEXT: __ENTRY_nocfg@0x[[ENTRY_ADDR]] (Entry Point):
// CHECK-NEXT: .{{[A-Za-z0-9]+}}:
// CHECK-NEXT:     00000008:   ret # Offset: 8
// CHECK-NEXT: DWARF CFI Instructions:
// CHECK-NEXT:     <empty>
// CHECK-NEXT: End of Function "nocfg"
// CHECK-EMPTY:
// CHECK-NEXT: Running src register safety analysis...
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(   adr     x0, __ENTRY_nocfg@0x[[ENTRY_ADDR]], src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: >)
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(  br      x0, src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: >)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: >)
// CHECK-NEXT:   Due to label, resetting the state before:     00000000:       ret # Offset: 8
// CHECK-NEXT:   SrcSafetyAnalysis::ComputeNext(  ret     x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT:     .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: After src register safety analysis:
// CHECK-NEXT: Binary Function "nocfg"  {
// CHECK-NEXT:   Number      : 3
// CHECK-NEXT:   State       : disassembled
// ...
// CHECK:        Secondary Entry Points : __ENTRY_nocfg@0x[[ENTRY_ADDR]]
// CHECK-NEXT: }
// CHECK-NEXT: .{{[A-Za-z0-9]+}}:
// CHECK-NEXT:     00000000:   adr     x0, __ENTRY_nocfg@0x[[ENTRY_ADDR]] # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     00000004:   br      x0 # UNKNOWN CONTROL FLOW # Offset: 4 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT: __ENTRY_nocfg@0x[[ENTRY_ADDR]] (Entry Point):
// CHECK-NEXT: .{{[A-Za-z0-9]+}}:
// CHECK-NEXT:     00000008:   ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT: DWARF CFI Instructions:
// CHECK-NEXT:     <empty>
// CHECK-NEXT: End of Function "nocfg"
// CHECK-EMPTY:
// PAUTH-NEXT:   Found call inst:     00000000:        br      x0 # UNKNOWN CONTROL FLOW # Offset: 4 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// PAUTH-NEXT:     Call destination reg: X0
// PAUTH-NEXT:     SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI{{[ \t]*$}}
// CHECK-NEXT:   Found RET inst:     00000000:         ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
// CHECK-NEXT:     RetReg: LR
// CHECK-NEXT:     SafeToDerefRegs: LR W30 W30_HI{{[ \t]*$}}

        .globl  auth_oracle
        .type   auth_oracle,@function
auth_oracle:
        autia   x0, x1
        ret
        .size auth_oracle, .-auth_oracle

// CHECK-LABEL:Analyzing function auth_oracle, AllocatorId = 1
// CHECK-NEXT: Binary Function "auth_oracle"  {
// CHECK-NEXT:   Number      : 4
// CHECK-NEXT:   State       : CFG constructed
// ...
// CHECK:        BB Layout   : [[BB0:[0-9a-zA-Z.]+]]
// CHECK-NEXT: }
// CHECK-NEXT: [[BB0]] (2 instructions, align : 1)
// CHECK-NEXT:   Entry Point
// CHECK-NEXT:     00000000:   autia   x0, x1
// CHECK-NEXT:     00000004:   ret
// CHECK-EMPTY:
// CHECK-NEXT: DWARF CFI Instructions:
// CHECK-NEXT:     <empty>
// CHECK-NEXT: End of Function "auth_oracle"
// CHECK-EMPTY:
// CHECK-NEXT: Running src register safety analysis...
// ...
// CHECK:      After src register safety analysis:
// CHECK-NEXT: Binary Function "auth_oracle"  {
// ...
// CHECK:      End of Function "auth_oracle"
// ...
// FPAC-NOT: Running dst register safety analysis
// FPAC-NOT: DstSafetyAnalysis::ComputeNext
// FPAC-NOT: {{.*dst-state.*}}
// AUTH-ORACLES:      Running dst register safety analysis...
// AUTH-ORACLES-NEXT:   DstSafetyAnalysis::ComputeNext(       ret     x30, dst-state<CannotEscapeUnchecked: , Insts: >)
// AUTH-ORACLES-NEXT:     .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: >)
// AUTH-ORACLES-NEXT:   DstSafetyAnalysis::ComputeNext(       autia   x0, x1, dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: >)
// AUTH-ORACLES-NEXT:     .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: >)
// AUTH-ORACLES-NEXT: After dst register safety analysis:
// AUTH-ORACLES-NEXT: Binary Function "auth_oracle"  {
// AUTH-ORACLES-NEXT:   Number      : 4
// AUTH-ORACLES-NEXT:   State       : CFG constructed
// ...
// AUTH-ORACLES:        BB Layout   : [[BB0]]
// AUTH-ORACLES-NEXT: }
// AUTH-ORACLES-NEXT: [[BB0]] (2 instructions, align : 1)
// AUTH-ORACLES-NEXT:   Entry Point
// AUTH-ORACLES-NEXT:     00000000:   autia   x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: >
// AUTH-ORACLES-NEXT:     00000004:   ret # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: >
// AUTH-ORACLES-EMPTY:
// AUTH-ORACLES-NEXT: DWARF CFI Instructions:
// AUTH-ORACLES-NEXT:     <empty>
// AUTH-ORACLES-NEXT: End of Function "auth_oracle"
// AUTH-ORACLES-EMPTY:
// AUTH-ORACLES-NEXT:   Found auth inst:     00000000:        autia   x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: >
// AUTH-ORACLES-NEXT:     Authenticated reg: X0
// AUTH-ORACLES-NEXT:     safe output registers: LR W30 W30_HI{{[ \t]*$}}
// AUTH-ORACLES-EMPTY:
// AUTH-ORACLES-NEXT: Running detailed dst register safety analysis...
// AUTH-ORACLES-NEXT:   DstSafetyAnalysis::ComputeNext(       ret     x30, dst-state<CannotEscapeUnchecked: , Insts: [0]()>)
// AUTH-ORACLES-NEXT:     .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: [0]()>)
// AUTH-ORACLES-NEXT:   DstSafetyAnalysis::ComputeNext(       autia   x0, x1, dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: [0]()>)
// AUTH-ORACLES-NEXT:     .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: [0](0x{{[0-9a-f]+}})>)
// AUTH-ORACLES-NEXT: After detailed dst register safety analysis:
// AUTH-ORACLES-NEXT: Binary Function "auth_oracle"  {
// AUTH-ORACLES-NEXT:   Number      : 4
// AUTH-ORACLES-NEXT:   State       : CFG constructed
// ...
// AUTH-ORACLES:        BB Layout   : [[BB0]]
// AUTH-ORACLES-NEXT: }
// AUTH-ORACLES-NEXT: [[BB0]] (2 instructions, align : 1)
// AUTH-ORACLES-NEXT:   Entry Point
// AUTH-ORACLES-NEXT:     00000000:   autia   x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: [0](0x{{[0-9a-f]+}})>
// AUTH-ORACLES-NEXT:     00000004:   ret # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: [0]()>
// AUTH-ORACLES-EMPTY:
// AUTH-ORACLES-NEXT: DWARF CFI Instructions:
// AUTH-ORACLES-NEXT:     <empty>
// AUTH-ORACLES-NEXT: End of Function "auth_oracle"
// AUTH-ORACLES-EMPTY:
// AUTH-ORACLES-NEXT:   Attaching leakage info to:     00000000:      autia   x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: [0](0x{{[0-9a-f]+}})>

// Gadget scanner should not crash on CFI instructions, including when debug-printing them.
// Note that the particular debug output is not checked, but BOLT should be
// compiled with assertions enabled to support -debug-only argument.

        .globl  cfi_inst_df
        .type   cfi_inst_df,@function
cfi_inst_df:
        .cfi_startproc
        sub     sp, sp, #16
        .cfi_def_cfa_offset 16
        add     sp, sp, #16
        .cfi_def_cfa_offset 0
        ret
        .size   cfi_inst_df, .-cfi_inst_df
        .cfi_endproc

        .globl  cfi_inst_nocfg
        .type   cfi_inst_nocfg,@function
cfi_inst_nocfg:
        .cfi_startproc
        sub     sp, sp, #16
        .cfi_def_cfa_offset 16

        adr     x0, 1f
        br      x0
1:
        add     sp, sp, #16
        .cfi_def_cfa_offset 0
        ret
        .size   cfi_inst_nocfg, .-cfi_inst_nocfg
        .cfi_endproc

// CHECK-LABEL:Analyzing function main, AllocatorId = 1
        .globl  main
        .type   main,@function
main:
        ret
        .size main, .-main
