diff options
| author | Nick Desaulniers <ndesaulniers@google.com> | 2019-09-25 22:28:27 +0000 | 
|---|---|---|
| committer | Nick Desaulniers <ndesaulniers@google.com> | 2019-09-25 22:28:27 +0000 | 
| commit | 93d87260f1f7b5ec6775fe88891e47a57e6392d6 (patch) | |
| tree | 00cec6aacace958a220e73a6e01671176798fb8b /llvm/test | |
| parent | 6023cf223446e3f7038d4b867635f47b2d26e194 (diff) | |
| download | bcm5719-llvm-93d87260f1f7b5ec6775fe88891e47a57e6392d6.tar.gz bcm5719-llvm-93d87260f1f7b5ec6775fe88891e47a57e6392d6.zip | |
[Verifier] add invariant check for callbr
Summary:
The list of indirect labels should ALWAYS have their blockaddresses as
argument operands to the callbr (but not necessarily the other way
around).  Add an invariant that checks this.
The verifier catches a bad test case that was added recently in r368478.
I think that was a simple mistake, and the test was made less strict in
regards to the precise addresses (as those weren't specifically the
point of the test).
This invariant will be used to find a reported bug.
Link: https://www.spinics.net/lists/arm-kernel/msg753473.html
Link: https://github.com/ClangBuiltLinux/linux/issues/649
Reviewers: craig.topper, void, chandlerc
Reviewed By: void
Subscribers: ychen, lebedev.ri, javed.absar, kristof.beyls, hiraditya, llvm-commits, srhines
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67196
llvm-svn: 372923
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll | 28 | ||||
| -rw-r--r-- | llvm/test/Verifier/callbr.ll | 50 | 
2 files changed, 64 insertions, 14 deletions
| diff --git a/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll b/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll index 579158568b6..58067946614 100644 --- a/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll +++ b/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll @@ -6,11 +6,11 @@  @l = common hidden local_unnamed_addr global i32 0, align 4 -; CHECK-LABEL: 0000000000000000 test1: -; CHECK-LABEL: 0000000000000018 $d.1: -; CHECK-LABEL: 0000000000000020 $x.2: +; CHECK-LABEL: test1: +; CHECK-LABEL: $d.1: +; CHECK-LABEL: $x.2:  ; CHECK-NEXT:    b #16 <$x.4+0x4> -; CHECK-LABEL: 000000000000002c $x.4: +; CHECK-LABEL: $x.4:  ; CHECK-NEXT:    b #4 <$x.4+0x4>  ; CHECK-NEXT:    mov w0, wzr  ; CHECK-NEXT:    ldr x30, [sp], #16 @@ -40,11 +40,11 @@ declare dso_local i32 @g(...) local_unnamed_addr  declare dso_local i32 @i(...) local_unnamed_addr -; CHECK-LABEL: 000000000000003c test2: -; CHECK:         bl #0 <test2+0x18> -; CHECK-LABEL: 0000000000000064 $d.5: -; CHECK-LABEL: 000000000000006c $x.6: -; CHECK-NEXT:    b #-24 <test2+0x18> +; CHECK-LABEL: test2: +; CHECK:         bl #0 <test2+0x10> +; CHECK-LABEL: $d.5: +; CHECK-LABEL: $x.6: +; CHECK-NEXT:    b #16 <$x.8+0x4>  define hidden i32 @test2() local_unnamed_addr {    %1 = load i32, i32* @l, align 4    %2 = icmp eq i32 %1, 0 @@ -57,7 +57,7 @@ define hidden i32 @test2() local_unnamed_addr {  6:                                                ; preds = %3    callbr void asm sideeffect "1: nop\0A\09.quad b\0A\09b ${1:l}\0A\09.quad ${0:c}", "i,X"(i32* null, i8* blockaddress(@test2, %7)) -          to label %10 [label %9] +          to label %10 [label %7]  7:                                                ; preds = %3    %8 = tail call i32 bitcast (i32 (...)* @i to i32 ()*)() @@ -70,11 +70,11 @@ define hidden i32 @test2() local_unnamed_addr {    ret i32 undef  } -; CHECK-LABEL: 0000000000000084 test3: -; CHECK-LABEL: 00000000000000a8 $d.9: -; CHECK-LABEL: 00000000000000b0 $x.10: +; CHECK-LABEL: test3: +; CHECK-LABEL: $d.9: +; CHECK-LABEL: $x.10:  ; CHECK-NEXT:    b #20 <$x.12+0x8> -; CHECK-LABEL: 00000000000000bc $x.12: +; CHECK-LABEL: $x.12:  ; CHECK-NEXT:    b #4 <$x.12+0x4>  ; CHECK-NEXT:    mov w0, wzr  ; CHECK-NEXT:    ldr x30, [sp], #16 diff --git a/llvm/test/Verifier/callbr.ll b/llvm/test/Verifier/callbr.ll new file mode 100644 index 00000000000..403cc573d0d --- /dev/null +++ b/llvm/test/Verifier/callbr.ll @@ -0,0 +1,50 @@ +; RUN: not opt -S %s -verify 2>&1 | FileCheck %s + +; CHECK: Indirect label missing from arglist. +define void @foo() { +  ; The %4 in the indirect label list is not found in the blockaddresses in the +  ; arg list (bad). +  callbr void asm sideeffect "${0:l} {1:l}", "X,X"(i8* blockaddress(@foo, %3), i8* blockaddress(@foo, %2)) +  to label %1 [label %4, label %2] +1: +  ret void +2: +  ret void +3: +  ret void +4: +  ret void +} + +; CHECK-NOT: Indirect label missing from arglist. +define void @bar() { +  ; %4 and %2 are both in the indirect label list and the arg list (good). +  callbr void asm sideeffect "${0:l} ${1:l}", "X,X"(i8* blockaddress(@bar, %4), i8* blockaddress(@bar, %2)) +  to label %1 [label %4, label %2] +1: +  ret void +2: +  ret void +3: +  ret void +4: +  ret void +} + +; CHECK-NOT: Indirect label missing from arglist. +define void @baz() { +  ; note %2 blockaddress. Such a case is possible when passing the address of +  ; a label as an input to the inline asm (both address of label and asm goto +  ; use blockaddress constants; we're testing that the indirect label list from +  ; the asm goto is in the arg list to the asm). +  callbr void asm sideeffect "${0:l} ${1:l} ${2:l}", "X,X,X"(i8* blockaddress(@baz, %4), i8* blockaddress(@baz, %2), i8* blockaddress(@baz, %3)) +  to label %1 [label %3, label %4] +1: +  ret void +2: +  ret void +3: +  ret void +4: +  ret void +} | 

