[CompactUnwind] Fix register encoding logic
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 8 Dec 2014 18:18:32 +0000 (18:18 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 8 Dec 2014 18:18:32 +0000 (18:18 +0000)
Fix a compact unwind encoding logic bug which would try to encode
more callee saved registers than it should, leading to early bail out
in the encoding logic and abusive use of DWARF frame mode unnecessarily.

Also remove no-compact-unwind.ll which was testing the wrong thing
based on this bug and move it to valid 'compact unwind' tests. Added
other few more tests too.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223676 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
test/CodeGen/X86/compact-unwind.ll
test/CodeGen/X86/no-compact-unwind.ll [deleted file]
test/MC/X86/compact-unwind.s [new file with mode: 0644]

index 60e223e5bd1e8e2af9a4c1d66a88dff1955513ba..03a1e02f188dab651949a967c0907f3477f76de4 100644 (file)
@@ -682,7 +682,7 @@ private:
     //     4       3
     //     5       3
     //
-    for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) {
+    for (unsigned i = 0; i < RegCount; ++i) {
       int CUReg = getCompactUnwindRegNum(SavedRegs[i]);
       if (CUReg == -1) return ~0U;
       SavedRegs[i] = CUReg;
index 9d3a1257288c935138574f3e35f513f2c2453806..d3b89a54e0b8491a26e918e196756f16023180f4 100644 (file)
@@ -1,12 +1,20 @@
 ; RUN: llc < %s -disable-fp-elim -mtriple x86_64-apple-darwin11 -mcpu corei7 | FileCheck -check-prefix=ASM %s
 ; RUN: llc < %s -disable-fp-elim -mtriple x86_64-apple-darwin11 -mcpu corei7 -filetype=obj -o - \
-; RUN:  | llvm-objdump -triple x86_64-apple-darwin11 -s - \
+; RUN:  | llvm-objdump -triple x86_64-apple-darwin11 -unwind-info - \
 ; RUN:  | FileCheck -check-prefix=CU %s
 ; RUN: llc < %s -disable-fp-elim -mtriple x86_64-apple-darwin11 -mcpu corei7 \
 ; RUN:  | llvm-mc -triple x86_64-apple-darwin11 -filetype=obj -o - \
-; RUN:  | llvm-objdump -triple x86_64-apple-darwin11 -s - \
+; RUN:  | llvm-objdump -triple x86_64-apple-darwin11 -unwind-info - \
 ; RUN:  | FileCheck -check-prefix=FROM-ASM %s
 
+; RUN: llc < %s -mtriple x86_64-apple-macosx10.8.0 -mcpu corei7 -filetype=obj -o - \
+; RUN:  | llvm-objdump -triple x86_64-apple-macosx10.8.0 -unwind-info - \
+; RUN:  | FileCheck -check-prefix=NOFP-CU %s
+; RUN: llc < %s -mtriple x86_64-apple-darwin11 -mcpu corei7 \
+; RUN:  | llvm-mc -triple x86_64-apple-darwin11 -filetype=obj -o - \
+; RUN:  | llvm-objdump -triple x86_64-apple-darwin11 -unwind-info - \
+; RUN:  | FileCheck -check-prefix=NOFP-FROM-ASM %s
+
 %ty = type { i8* }
 
 @gv = external global i32
 ; Even though we can't encode %rax into the compact unwind, We still want to be
 ; able to generate a compact unwind encoding in this particular case.
 
-; CU:      Contents of section __compact_unwind:
-; CU-NEXT: 0020 00000000 00000000 1e000000 01000101
-; CU-NEXT: 0030 00000000 00000000 00000000 00000000
+; CU:    Contents of __compact_unwind section:
+; CU-NEXT:      Entry at offset 0x0:
+; CU-NEXT:        start:                0x0 _test0
+; CU-NEXT:        length:               0x1e
+; CU-NEXT:        compact encoding:     0x01010001
 
-; FROM-ASM:      Contents of section __compact_unwind:
-; FROM-ASM-NEXT: 0020 00000000 00000000 1e000000 01000101
-; FROM-ASM-NEXT: 0030 00000000 00000000 00000000 00000000
+; FROM-ASM:    Contents of __compact_unwind section:
+; FROM-ASM-NEXT:      Entry at offset 0x0:
+; FROM-ASM-NEXT:        start:                0x0 _test0
+; FROM-ASM-NEXT:        length:               0x1e
+; FROM-ASM-NEXT:        compact encoding:     0x01010001
 
-define i8* @foo(i64 %size) {
+define i8* @test0(i64 %size) {
   %addr = alloca i64, align 8
   %tmp20 = load i32* @gv, align 4
   %tmp21 = call i32 @bar()
@@ -39,3 +51,61 @@ define i8* @foo(i64 %size) {
 }
 
 declare i32 @bar()
+
+%"struct.dyld::MappedRanges" = type { [400 x %struct.anon], %"struct.dyld::MappedRanges"* }
+%struct.anon = type { %class.ImageLoader*, i64, i64 }
+%class.ImageLoader = type { i32 (...)**, i8*, i8*, i32, i64, i64, i32, i32, %"struct.ImageLoader::recursive_lock"*, i16, i16, [4 x i8] }
+%"struct.ImageLoader::recursive_lock" = type { i32, i32 }
+
+@G1 = external hidden global %"struct.dyld::MappedRanges", align 8
+
+declare void @OSMemoryBarrier() optsize
+
+; Test the code below uses UNWIND_X86_64_MODE_STACK_IMMD compact unwind
+; encoding.
+
+; NOFP-CU:      Entry at offset 0x20:
+; NOFP-CU-NEXT:        start:                0x1d _test1
+; NOFP-CU-NEXT:        length:               0x42
+; NOFP-CU-NEXT:        compact encoding:     0x02040c0a
+
+; NOFP-FROM-ASM:      Entry at offset 0x20:
+; NOFP-FROM-ASM-NEXT:        start:                0x1d _test1
+; NOFP-FROM-ASM-NEXT:        length:               0x42
+; NOFP-FROM-ASM-NEXT:        compact encoding:     0x02040c0a
+
+define void @test1(%class.ImageLoader* %image) optsize ssp uwtable {
+entry:
+  br label %for.cond1.preheader
+
+for.cond1.preheader:                              ; preds = %for.inc10, %entry
+  %p.019 = phi %"struct.dyld::MappedRanges"* [ @G1, %entry ], [ %1, %for.inc10 ]
+  br label %for.body3
+
+for.body3:                                        ; preds = %for.inc, %for.cond1.preheader
+  %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.inc ]
+  %image4 = getelementptr inbounds %"struct.dyld::MappedRanges"* %p.019, i64 0, i32 0, i64 %indvars.iv, i32 0
+  %0 = load %class.ImageLoader** %image4, align 8
+  %cmp5 = icmp eq %class.ImageLoader* %0, %image
+  br i1 %cmp5, label %if.then, label %for.inc
+
+if.then:                                          ; preds = %for.body3
+  tail call void @OSMemoryBarrier() optsize
+  store %class.ImageLoader* null, %class.ImageLoader** %image4, align 8
+  br label %for.inc
+
+for.inc:                                          ; preds = %if.then, %for.body3
+  %indvars.iv.next = add i64 %indvars.iv, 1
+  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+  %exitcond = icmp eq i32 %lftr.wideiv, 400
+  br i1 %exitcond, label %for.inc10, label %for.body3
+
+for.inc10:                                        ; preds = %for.inc
+  %next = getelementptr inbounds %"struct.dyld::MappedRanges"* %p.019, i64 0, i32 1
+  %1 = load %"struct.dyld::MappedRanges"** %next, align 8
+  %cmp = icmp eq %"struct.dyld::MappedRanges"* %1, null
+  br i1 %cmp, label %for.end11, label %for.cond1.preheader
+
+for.end11:                                        ; preds = %for.inc10
+  ret void
+}
diff --git a/test/CodeGen/X86/no-compact-unwind.ll b/test/CodeGen/X86/no-compact-unwind.ll
deleted file mode 100644 (file)
index 991cd4e..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-; RUN: llc < %s -mtriple x86_64-apple-macosx10.8.0 -mcpu corei7 -filetype=obj -o - \
-; RUN:  | llvm-objdump -triple x86_64-apple-macosx10.8.0 -s - \
-; RUN:  | FileCheck -check-prefix=CU %s
-; RUN: llc < %s -mtriple x86_64-apple-darwin11 -mcpu corei7 \
-; RUN:  | llvm-mc -triple x86_64-apple-darwin11 -filetype=obj -o - \
-; RUN:  | llvm-objdump -triple x86_64-apple-darwin11 -s - \
-; RUN:  | FileCheck -check-prefix=FROM-ASM %s
-
-%"struct.dyld::MappedRanges" = type { [400 x %struct.anon], %"struct.dyld::MappedRanges"* }
-%struct.anon = type { %class.ImageLoader*, i64, i64 }
-%class.ImageLoader = type { i32 (...)**, i8*, i8*, i32, i64, i64, i32, i32, %"struct.ImageLoader::recursive_lock"*, i16, i16, [4 x i8] }
-%"struct.ImageLoader::recursive_lock" = type { i32, i32 }
-
-@G1 = external hidden global %"struct.dyld::MappedRanges", align 8
-
-declare void @OSMemoryBarrier() optsize
-
-; This compact unwind encoding indicates that we could not generate correct
-; compact unwind encodings for this function. This then defaults to using the
-; DWARF EH frame.
-
-; CU:      Contents of section __compact_unwind:
-; CU-NEXT: 0048 00000000 00000000 42000000 00000004
-; CU-NEXT: 0058 00000000 00000000 00000000 00000000
-
-; FROM-ASM:      Contents of section __compact_unwind:
-; FROM-ASM-NEXT: 0048 00000000 00000000 42000000 00000004
-; FROM-ASM-NEXT: 0058 00000000 00000000 00000000 00000000
-
-define void @func(%class.ImageLoader* %image) optsize ssp uwtable {
-entry:
-  br label %for.cond1.preheader
-
-for.cond1.preheader:                              ; preds = %for.inc10, %entry
-  %p.019 = phi %"struct.dyld::MappedRanges"* [ @G1, %entry ], [ %1, %for.inc10 ]
-  br label %for.body3
-
-for.body3:                                        ; preds = %for.inc, %for.cond1.preheader
-  %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.inc ]
-  %image4 = getelementptr inbounds %"struct.dyld::MappedRanges"* %p.019, i64 0, i32 0, i64 %indvars.iv, i32 0
-  %0 = load %class.ImageLoader** %image4, align 8
-  %cmp5 = icmp eq %class.ImageLoader* %0, %image
-  br i1 %cmp5, label %if.then, label %for.inc
-
-if.then:                                          ; preds = %for.body3
-  tail call void @OSMemoryBarrier() optsize
-  store %class.ImageLoader* null, %class.ImageLoader** %image4, align 8
-  br label %for.inc
-
-for.inc:                                          ; preds = %if.then, %for.body3
-  %indvars.iv.next = add i64 %indvars.iv, 1
-  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
-  %exitcond = icmp eq i32 %lftr.wideiv, 400
-  br i1 %exitcond, label %for.inc10, label %for.body3
-
-for.inc10:                                        ; preds = %for.inc
-  %next = getelementptr inbounds %"struct.dyld::MappedRanges"* %p.019, i64 0, i32 1
-  %1 = load %"struct.dyld::MappedRanges"** %next, align 8
-  %cmp = icmp eq %"struct.dyld::MappedRanges"* %1, null
-  br i1 %cmp, label %for.end11, label %for.cond1.preheader
-
-for.end11:                                        ; preds = %for.inc10
-  ret void
-}
diff --git a/test/MC/X86/compact-unwind.s b/test/MC/X86/compact-unwind.s
new file mode 100644 (file)
index 0000000..82be239
--- /dev/null
@@ -0,0 +1,72 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump -unwind-info - | FileCheck %s
+
+       .section        __TEXT,__text,regular,pure_instructions
+       .macosx_version_min 10, 10
+
+# Check that we emit compact-unwind info with UNWIND_X86_MODE_STACK_IND encoding
+
+# CHECK: Contents of __compact_unwind section:
+# CHECK-NEXT:   Entry at offset 0x0:
+# CHECK-NEXT:     start:                0x0 _test0
+# CHECK-NEXT:     length:               0x15
+# CHECK-NEXT:     compact encoding:     0x03056804
+       .globl  _test0
+_test0:                                  ## @test0
+       .cfi_startproc
+## BB#0:                                ## %entry
+       pushq   %rbp
+Ltmp0:
+       .cfi_def_cfa_offset 16
+       pushq   %rbx
+Ltmp1:
+       .cfi_def_cfa_offset 24
+       subq    $14408, %rsp            ## imm = 0x3848
+Ltmp2:
+       .cfi_def_cfa_offset 14432
+Ltmp3:
+       .cfi_offset %rbx, -24
+Ltmp4:
+       .cfi_offset %rbp, -16
+       xorl    %eax, %eax
+       addq    $14408, %rsp            ## imm = 0x3848
+       popq    %rbx
+       popq    %rbp
+       retq
+       .cfi_endproc
+
+# Check that we emit compact-unwind info with UNWIND_X86_MODE_STACK_IMMD encoding
+
+# CHECK:   Entry at offset 0x20:
+# CHECK-NEXT:     start:                0x15 _test1
+# CHECK-NEXT:     length:               0x15
+# CHECK-NEXT:     compact encoding:     0x02360804
+       .globl  _test1
+_test1:                                  ## @test1
+       .cfi_startproc
+## BB#0:                                ## %entry
+       pushq   %rbp
+Ltmp10:
+       .cfi_def_cfa_offset 16
+       pushq   %rbx
+Ltmp11:
+       .cfi_def_cfa_offset 24
+       subq    $408, %rsp              ## imm = 0x198
+Ltmp12:
+       .cfi_def_cfa_offset 432
+Ltmp13:
+       .cfi_offset %rbx, -24
+Ltmp14:
+       .cfi_offset %rbp, -16
+       xorl    %eax, %eax
+       addq    $408, %rsp              ## imm = 0x198
+       popq    %rbx
+       popq    %rbp
+       retq
+       .cfi_endproc
+
+       .section        __TEXT,__cstring,cstring_literals
+L_.str:                                 ## @.str
+       .asciz  "%d\n"
+
+
+.subsections_via_symbols