# REQUIRES: x86 # RUN: rm -rf %t; mkdir %t # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/test.o # RUN: %lld -lSystem --icf=all -o %t/test %t/test.o # RUN: llvm-objdump --macho --syms -d %t/test | FileCheck %s # CHECK: _main: # CHECK-NEXT: callq _foo2_ref # CHECK-NEXT: callq _foo2_ref # CHECK-NEXT: callq _foo2_neg_offset_ref # CHECK-NEXT: callq _foo2_neg_offset_ref # CHECK-NEXT: callq _foo2_pos_offset_ref # CHECK-NEXT: callq _foo2_pos_offset_ref # CHECK-NEXT: callq _bar2_ref # CHECK-NEXT: callq _bar2_ref # CHECK-NEXT: callq _baz2_ref # CHECK-NEXT: callq _baz2_ref # CHECK-NEXT: callq _qux2_ref # CHECK-NEXT: callq _qux2_ref # CHECK-NEXT: callq _sub_str_a_b # CHECK-NEXT: callq _sub_str_b_a # CHECK-NEXT: callq _sub_lit_a_b # CHECK-NEXT: callq _sub_lit_b_a # CHECK: [[#%.16x,FOO:]] l O __TEXT,__cstring _foo1 # CHECK-NEXT: [[#%.16x,FOO:]] l O __TEXT,__cstring _foo2 # CHECK-NEXT: [[#%.16x,BAR:]] l O __TEXT,__cstring _bar1 # CHECK-NEXT: [[#%.16x,BAR:]] l O __TEXT,__cstring _bar2 # CHECK-NEXT: [[#%.16x,BAZ:]] l O __TEXT,__literals _baz1 # CHECK-NEXT: [[#%.16x,BAZ:]] l O __TEXT,__literals _baz2 # CHECK-NEXT: [[#%.16x,QUX:]] l O __TEXT,__literals _qux1 # CHECK-NEXT: [[#%.16x,QUX:]] l O __TEXT,__literals _qux2 # CHECK-NEXT: [[#%.16x,FOO_REF:]] l F __TEXT,__text _foo1_ref # CHECK-NEXT: [[#%.16x,FOO_REF:]] l F __TEXT,__text _foo2_ref # CHECK-NEXT: [[#%.16x,FOO_NEG:]] l F __TEXT,__text _foo1_neg_offset_ref # CHECK-NEXT: [[#%.16x,FOO_NEG]] l F __TEXT,__text _foo2_neg_offset_ref # CHECK-NEXT: [[#%.16x,FOO_POS:]] l F __TEXT,__text _foo1_pos_offset_ref # CHECK-NEXT: [[#%.16x,FOO_POS]] l F __TEXT,__text _foo2_pos_offset_ref # CHECK-NEXT: [[#%.16x,BAR_REF:]] l F __TEXT,__text _bar1_ref # CHECK-NEXT: [[#%.16x,BAR_REF:]] l F __TEXT,__text _bar2_ref # CHECK-NEXT: [[#%.16x,BAZ_REF:]] l F __TEXT,__text _baz1_ref # CHECK-NEXT: [[#%.16x,BAZ_REF:]] l F __TEXT,__text _baz2_ref # CHECK-NEXT: [[#%.16x,QUX_REF:]] l F __TEXT,__text _qux1_ref # CHECK-NEXT: [[#%.16x,QUX_REF:]] l F __TEXT,__text _qux2_ref ## _foo1 vs _bar1: same section, different offsets ## _foo1 vs _baz1: same offset, different sections .cstring _foo1: .asciz "foo" _foo2: .asciz "foo" _bar1: .asciz "bar" _bar2: .asciz "bar" .literal8 _baz1: .quad 0xdead _baz2: .quad 0xdead _qux1: .quad 0xbeef _qux2: .quad 0xbeef .text _foo1_ref: leaq _foo1(%rip), %rax _foo2_ref: leaq _foo2(%rip), %rax _foo1_neg_offset_ref: ## Check that we can correctly handle `_foo1-32` even though it points outside ## the __cstring section. leaq _foo1-32(%rip), %rax _foo2_neg_offset_ref: leaq _foo2-32(%rip), %rax _foo1_pos_offset_ref: leaq _foo1+4(%rip), %rax _foo2_pos_offset_ref: ## Although `_foo2+4` points at _bar1 in the input object file, we shouldn't ## dedup references to _foo2+4 with references to _bar1. leaq _foo2+4(%rip), %rax _bar1_ref: leaq _bar1(%rip), %rax _bar2_ref: leaq _bar2(%rip), %rax _baz1_ref: movq _baz1(%rip), %rax _baz2_ref: movq _baz2(%rip), %rax _qux1_ref: movq _qux1(%rip), %rax _qux2_ref: movq _qux2(%rip), %rax ## _sub_str_a_b and _sub_str_b_a should not be folded: They contain relocations ## against the same string symbols, but in a different order and hence ## return different numbers. _sub_str_a_b: leaq _foo2(%rip), %rdx leaq _bar2(%rip), %rax subq %rdx, %rax _sub_str_b_a: leaq _bar2(%rip), %rdx leaq _foo2(%rip), %rax subq %rdx, %rax ## Same with literals instead of strings. _sub_lit_a_b: movq _baz2(%rip), %rax subq _qux2(%rip), %rax _sub_lit_b_a: movq _qux2(%rip), %rax subq _baz2(%rip), %rax .globl _main _main: callq _foo1_ref callq _foo2_ref callq _foo1_neg_offset_ref callq _foo2_neg_offset_ref callq _foo1_pos_offset_ref callq _foo2_pos_offset_ref callq _bar1_ref callq _bar2_ref callq _baz1_ref callq _baz2_ref callq _qux1_ref callq _qux2_ref callq _sub_str_a_b callq _sub_str_b_a callq _sub_lit_a_b callq _sub_lit_b_a .subsections_via_symbols