[llvm] 05f7b68 - [llvm-libtool-darwin] Add support for LLVM bitcode files

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 29 12:01:02 PDT 2020


Author: Paul-Antoine Arras
Date: 2020-10-29T12:00:44-07:00
New Revision: 05f7b682192b79090b99f01ac7ea62ceaad631b7

URL: https://github.com/llvm/llvm-project/commit/05f7b682192b79090b99f01ac7ea62ceaad631b7
DIFF: https://github.com/llvm/llvm-project/commit/05f7b682192b79090b99f01ac7ea62ceaad631b7.diff

LOG: [llvm-libtool-darwin] Add support for LLVM bitcode files

This diff adds support for LLVM bitcode objects to llvm-libtool-darwin.

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D88722

Added: 
    llvm/test/tools/llvm-libtool-darwin/Inputs/arm64-ios.ll
    llvm/test/tools/llvm-libtool-darwin/Inputs/arm64e-ios.ll
    llvm/test/tools/llvm-libtool-darwin/Inputs/armv7-ios.ll
    llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx-2.ll
    llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx.ll
    llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64h-osx.ll
    llvm/test/tools/llvm-libtool-darwin/universal-bitcode-flattening.test
    llvm/test/tools/llvm-libtool-darwin/universal-bitcode-output.test
    llvm/test/tools/llvm-libtool-darwin/universal-object-flattening.test
    llvm/test/tools/llvm-libtool-darwin/universal-object-output.test

Modified: 
    llvm/test/tools/llvm-libtool-darwin/archive-flattening.test
    llvm/test/tools/llvm-libtool-darwin/cpu-subtype-matching.test
    llvm/test/tools/llvm-libtool-darwin/create-static-lib.test
    llvm/test/tools/llvm-libtool-darwin/filelist.test
    llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp

Removed: 
    llvm/test/tools/llvm-libtool-darwin/universal-file-flattening.test
    llvm/test/tools/llvm-libtool-darwin/universal-output.test


################################################################################
diff  --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64-ios.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64-ios.ll
new file mode 100644
index 000000000000..d3b816e555fc
--- /dev/null
+++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64-ios.ll
@@ -0,0 +1,6 @@
+target triple = "arm64-apple-ios8.0.0"
+
+define void @_arm64(){
+entry:
+	ret void
+}

diff  --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64e-ios.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64e-ios.ll
new file mode 100644
index 000000000000..ac31210afd2d
--- /dev/null
+++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64e-ios.ll
@@ -0,0 +1,6 @@
+target triple = "arm64e-apple-ios8.0.0"
+
+define void @_arm64e(){
+entry:
+	ret void
+}

diff  --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/armv7-ios.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/armv7-ios.ll
new file mode 100644
index 000000000000..5b48eb088429
--- /dev/null
+++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/armv7-ios.ll
@@ -0,0 +1,6 @@
+target triple = "thumbv7-apple-ios8.0.0"
+
+define void @_armv7() {
+entry:
+	ret void
+}
\ No newline at end of file

diff  --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx-2.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx-2.ll
new file mode 100644
index 000000000000..d10523d0cb0b
--- /dev/null
+++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx-2.ll
@@ -0,0 +1,6 @@
+target triple = "x86_64-apple-macosx10.15.0"
+
+define void @_x86_64_2() {
+entry:
+	ret void
+}
\ No newline at end of file

diff  --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx.ll
new file mode 100644
index 000000000000..2511aa89a58d
--- /dev/null
+++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx.ll
@@ -0,0 +1,6 @@
+target triple = "x86_64-apple-macosx10.15.0"
+
+define void @_x86_64() {
+entry:
+	ret void
+}
\ No newline at end of file

diff  --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64h-osx.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64h-osx.ll
new file mode 100644
index 000000000000..6b80932936c3
--- /dev/null
+++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64h-osx.ll
@@ -0,0 +1,6 @@
+target triple = "x86_64h-apple-macosx10.15.0"
+
+define void @_x86_64_h() {
+entry:
+	ret void
+}
\ No newline at end of file

diff  --git a/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test b/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test
index fa3200ec00b7..bfe2659e666d 100644
--- a/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test
+++ b/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test
@@ -2,17 +2,19 @@
 
 # RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o
 # RUN: yaml2obj %S/Inputs/input2.yaml -o %t-input2.o
+# RUN: llvm-as %S/Inputs/x86_64-osx.ll -o %t-x86_64.bc
 
 ## Input a correct archive:
 # RUN: rm -f %t.correct.ar
-# RUN: llvm-ar cr %t.correct.ar %t-input1.o %t-input2.o
+# RUN: llvm-ar cr %t.correct.ar %t-x86_64.bc %t-input1.o %t-input2.o
 # RUN: llvm-libtool-darwin -static -o %t.lib %t.correct.ar
 
 ## Check that binaries are present:
 # RUN: llvm-ar t %t.lib | \
 # RUN:   FileCheck %s --check-prefix=CHECK-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
 
-# CHECK-NAMES:      [[PREFIX]]-input1.o
+# CHECK-NAMES: [[PREFIX]]-x86_64.bc
+# CHECK-NAMES-NEXT: [[PREFIX]]-input1.o
 # CHECK-NAMES-NEXT: [[PREFIX]]-input2.o
 
 ## Check that symbols are present:
@@ -20,6 +22,7 @@
 # RUN:   FileCheck %s --check-prefix=CHECK-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
 
 # CHECK-SYMBOLS:      Archive map
+# CHECK-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc
 # CHECK-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o
 # CHECK-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o
 # CHECK-SYMBOLS-EMPTY:
@@ -30,24 +33,27 @@
 
 # FORMAT:      Archive : [[ARCHIVE]]
 # FORMAT-NEXT: __.SYMDEF
+# FORMAT-NEXT: [[PREFIX]]-x86_64.bc
 # FORMAT-NEXT: [[PREFIX]]-input1.o
 # FORMAT-NEXT: [[PREFIX]]-input2.o
 # FORMAT-NOT:  {{.}}
 
-## Passing both archive and object file:
-# RUN: llvm-libtool-darwin -static -o %t.lib %t-input2.o %t.correct.ar %t-input1.o
+## Passing both archive, bitcode and object file:
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-x86_64.bc %t.correct.ar %t-input1.o
 # RUN: llvm-ar t %t.lib | \
 # RUN:   FileCheck %s --check-prefix=BOTH-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
 # RUN: llvm-nm --print-armap %t.lib | \
 # RUN:   FileCheck %s --check-prefix=BOTH-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
 
-# BOTH-NAMES:      [[PREFIX]]-input2.o
+# BOTH-NAMES:      [[PREFIX]]-x86_64.bc
+# BOTH-NAMES-NEXT: [[PREFIX]]-x86_64.bc
 # BOTH-NAMES-NEXT: [[PREFIX]]-input1.o
 # BOTH-NAMES-NEXT: [[PREFIX]]-input2.o
 # BOTH-NAMES-NEXT: [[PREFIX]]-input1.o
 
 # BOTH-SYMBOLS:      Archive map
-# BOTH-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o
+# BOTH-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc
+# BOTH-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc
 # BOTH-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o
 # BOTH-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o
 # BOTH-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o

diff  --git a/llvm/test/tools/llvm-libtool-darwin/cpu-subtype-matching.test b/llvm/test/tools/llvm-libtool-darwin/cpu-subtype-matching.test
index 4789361ba693..e0eb37d416cf 100644
--- a/llvm/test/tools/llvm-libtool-darwin/cpu-subtype-matching.test
+++ b/llvm/test/tools/llvm-libtool-darwin/cpu-subtype-matching.test
@@ -1,22 +1,26 @@
 ## This test checks that the CPU subtype matching logic is handled correctly.
 
-# RUN: yaml2obj %s --docnum=1 -o %t.armv6
-# RUN: yaml2obj %s --docnum=2 -o %t.armv7
+# RUN: yaml2obj %s --docnum=1 -o %t-armv6.obj
+# RUN: yaml2obj %s --docnum=2 -o %t-armv7.obj
+# RUN: llvm-as %p/Inputs/arm64-ios.ll -o %t-arm64.bc
+# RUN: llvm-as %p/Inputs/armv7-ios.ll -o %t-armv7.bc
 
-# RUN: llvm-libtool-darwin -static -o %t.lib %t.armv6 %t.armv7 -arch_only armv7
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-armv6.obj %t-armv7.obj %t-arm64.bc %t-armv7.bc -arch_only armv7
 
 ## Check that only armv7 binary is present:
 # RUN: llvm-ar t %t.lib | \
 # RUN:   FileCheck %s --check-prefix=ARM-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
 
-# ARM-NAMES: [[PREFIX]].armv7
+# ARM-NAMES: [[PREFIX]]-armv7.obj
+# ARM-NAMES-NEXT: [[PREFIX]]-armv7.bc
 
 ## Check that only armv7 symbol is present:
 # RUN: llvm-nm --print-armap %t.lib | \
 # RUN:   FileCheck %s --check-prefix=ARM-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
 
 # ARM-SYMBOLS:      Archive map
-# ARM-SYMBOLS-NEXT: _armv7 in [[PREFIX]].armv7
+# ARM-SYMBOLS-NEXT: _armv7 in [[PREFIX]]-armv7.obj
+# ARM-SYMBOLS-NEXT: _armv7 in [[PREFIX]]-armv7.bc
 # ARM-SYMBOLS-EMPTY:
 
 ## armv6.yaml
@@ -133,23 +137,27 @@ LinkEditData:
     - ''
 ...
 
-# RUN: yaml2obj %s --docnum=3 -o %t.x86_64
-# RUN: yaml2obj %s --docnum=4 -o %t.x86_64_h
+# RUN: yaml2obj %s --docnum=3 -o %t-x86_64.obj
+# RUN: yaml2obj %s --docnum=4 -o %t-x86_64_h.obj
+# RUN: llvm-as %p/Inputs/x86_64-osx.ll -o %t-x86_64.bc
+# RUN: llvm-as %p/Inputs/x86_64h-osx.ll -o %t-x86_64_h.bc
 
-# RUN: llvm-libtool-darwin -static -o %t.lib %t.x86_64 %t.x86_64_h -arch_only x86_64
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-x86_64.obj %t-x86_64_h.obj %t-x86_64.bc %t-x86_64_h.bc -arch_only x86_64
 
 ## Check that only x86_64 binary is present:
 # RUN: llvm-ar t %t.lib | \
 # RUN:   FileCheck %s --check-prefix=X86-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
 
-# X86-NAMES: [[PREFIX]].x86_64
+# X86-NAMES: [[PREFIX]]-x86_64.obj
+# X86-NAMES-NEXT: [[PREFIX]]-x86_64.bc
 
 ## Check that only x86_64 symbol is present:
 # RUN: llvm-nm --print-armap %t.lib | \
 # RUN:   FileCheck %s --check-prefix=X86-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
 
 # X86-SYMBOLS:      Archive map
-# X86-SYMBOLS-NEXT: _x86_64 in [[PREFIX]].x86_64
+# X86-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.obj
+# X86-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc
 # X86-SYMBOLS-EMPTY:
 
 ## x86_64.yaml

diff  --git a/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test b/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test
index 6c96782b57d2..92baea34c7bc 100644
--- a/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test
+++ b/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test
@@ -2,9 +2,10 @@
 
 # RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o
 # RUN: yaml2obj %S/Inputs/input2.yaml -o %t-input2.o
+# RUN: llvm-as %S/Inputs/x86_64-osx.ll -o %t-x86_64.bc
 
 # RUN: rm -rf %t.lib
-# RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o %t-input2.o
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o %t-input2.o %t-x86_64.bc
 
 ## Check that binaries are present:
 # RUN: llvm-ar t %t.lib | \
@@ -12,6 +13,7 @@
 
 # CHECK-NAMES:      [[PREFIX]]-input1.o
 # CHECK-NAMES-NEXT: [[PREFIX]]-input2.o
+# CHECK-NAMES-NEXT: [[PREFIX]]-x86_64.bc
 
 ## Check that symbols are present:
 # RUN: llvm-nm --print-armap %t.lib | \
@@ -20,6 +22,7 @@
 # CHECK-SYMBOLS:      Archive map
 # CHECK-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o
 # CHECK-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o
+# CHECK-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc
 # CHECK-SYMBOLS-EMPTY:
 
 ## Check that output archive is in Darwin format:
@@ -30,6 +33,7 @@
 # FORMAT-NEXT: __.SYMDEF
 # FORMAT-NEXT: [[PREFIX]]-input1.o
 # FORMAT-NEXT: [[PREFIX]]-input2.o
+# FORMAT-NEXT: [[PREFIX]]-x86_64.bc
 # FORMAT-NOT:  {{.}}
 
 ## Check that the output file is overwritten:

diff  --git a/llvm/test/tools/llvm-libtool-darwin/filelist.test b/llvm/test/tools/llvm-libtool-darwin/filelist.test
index 5e70309cbe48..bb606f0585fa 100644
--- a/llvm/test/tools/llvm-libtool-darwin/filelist.test
+++ b/llvm/test/tools/llvm-libtool-darwin/filelist.test
@@ -2,10 +2,12 @@
 
 # RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o
 # RUN: yaml2obj %S/Inputs/input2.yaml -o %t-input2.o
+# RUN: llvm-as %S/Inputs/x86_64-osx.ll -o %t-x86_64.bc
 
 ## Passing files in a listfile:
 # RUN: echo %t-input1.o >  %t.files.txt
 # RUN: echo %t-input2.o >> %t.files.txt
+# RUN: echo %t-x86_64.bc >> %t.files.txt
 # RUN: llvm-libtool-darwin -static -o %t.lib -filelist %t.files.txt
 
 ## Check that binaries are present:
@@ -14,6 +16,7 @@
 
 # CHECK-NAMES:      [[PREFIX]]-input1.o
 # CHECK-NAMES-NEXT: [[PREFIX]]-input2.o
+# CHECK-NAMES-NEXT: [[PREFIX]]-x86_64.bc
 
 ## Check that symbols are present:
 # RUN: llvm-nm --print-armap %t.lib | \
@@ -22,6 +25,7 @@
 # CHECK-SYMBOLS:      Archive map
 # CHECK-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o
 # CHECK-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o
+# CHECK-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc
 # CHECK-SYMBOLS-EMPTY:
 
 # RUN: rm -rf %t/dirname && mkdir -p %t/dirname

diff  --git a/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-flattening.test b/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-flattening.test
new file mode 100644
index 000000000000..693b9f693813
--- /dev/null
+++ b/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-flattening.test
@@ -0,0 +1,86 @@
+## This test checks that a universal bitcode file is flattened correctly.
+
+# RUN: llvm-as %S/Inputs/arm64-ios.ll -o %t-arm64.bc
+# RUN: llvm-as %S/Inputs/x86_64-osx.ll -o %t-x86_64.bc
+# RUN: llvm-as %S/Inputs/x86_64-osx-2.ll -o %t-x86_64-2.bc
+# RUN: llvm-lipo %t-arm64.bc %t-x86_64.bc -create -output %t-universal.o
+
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-universal.o -arch_only arm64
+
+## Check that the binary is present:
+# RUN: llvm-ar t %t.lib | \
+# RUN:   FileCheck %s --check-prefix=CHECK-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
+
+# CHECK-NAMES: [[PREFIX]]-universal.o
+
+## Check that symbols are present:
+# RUN: llvm-nm --print-armap %t.lib | \
+# RUN:   FileCheck %s --check-prefix=CHECK-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
+
+# CHECK-SYMBOLS:      Archive map
+# CHECK-SYMBOLS-NEXT: _arm64 in [[PREFIX]]-universal.o
+# CHECK-SYMBOLS-EMPTY:
+
+## Check that the output archive is in Darwin format:
+# RUN: llvm-objdump --macho --archive-headers %t.lib | \
+# RUN:   FileCheck %s --check-prefix=FORMAT -DPREFIX=%basename_t.tmp -DARCHIVE=%t.lib
+
+# FORMAT:      Archive : [[ARCHIVE]]
+# FORMAT-NEXT: __.SYMDEF
+# FORMAT-NEXT: [[PREFIX]]-universal.o
+# FORMAT-NOT:  {{.}}
+
+## Passing both a universal file and a bitcode file:
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-universal.o %t-x86_64-2.bc -arch_only x86_64
+# RUN: llvm-ar t %t.lib | \
+# RUN:   FileCheck %s --check-prefix=BOTH-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
+# RUN: llvm-nm --print-armap %t.lib | \
+# RUN:   FileCheck %s --check-prefix=BOTH-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
+
+# BOTH-NAMES:      [[PREFIX]]-universal.o
+# BOTH-NAMES-NEXT: [[PREFIX]]-x86_64-2.bc
+
+# BOTH-SYMBOLS:      Archive map
+# BOTH-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-universal.o
+# BOTH-SYMBOLS-NEXT: _x86_64_2 in [[PREFIX]]-x86_64-2.bc
+# BOTH-SYMBOLS-EMPTY:
+
+## Passing both a universal file and a bitcode file but filtering out the object file:
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-universal.o %t-x86_64.bc -arch_only arm64
+# RUN: llvm-ar t %t.lib | \
+# RUN:   FileCheck %s --check-prefix=CHECK-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
+# RUN: llvm-nm --print-armap %t.lib | \
+# RUN:   FileCheck %s --check-prefix=CHECK-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
+
+## Universal file containing an archive:
+# RUN: rm -f %t.ar
+# RUN: llvm-ar cr %t.ar %t-x86_64.bc %t-x86_64-2.bc
+# RUN: llvm-lipo %t.ar -create -output %t-fat-with-archive.o
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-fat-with-archive.o
+# RUN: llvm-ar t %t.lib | \
+# RUN:   FileCheck %s --check-prefix=ARCHIVE-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
+# RUN: llvm-nm --print-armap %t.lib | \
+# RUN:   FileCheck %s --check-prefix=ARCHIVE-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
+
+# ARCHIVE-NAMES:      [[PREFIX]]-x86_64.bc
+# ARCHIVE-NAMES-NEXT: [[PREFIX]]-x86_64-2.bc
+
+# ARCHIVE-SYMBOLS:      Archive map
+# ARCHIVE-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc
+# ARCHIVE-SYMBOLS-NEXT: _x86_64_2 in [[PREFIX]]-x86_64-2.bc
+# ARCHIVE-SYMBOLS-EMPTY:
+
+## Allow arch_only to be specified more than once (pick the last one):
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-universal.o -arch_only arm64 -arch_only x86_64
+# RUN: llvm-ar t %t.lib | \
+# RUN:   FileCheck %s --check-prefix=DOUBLE-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
+# RUN: llvm-nm --print-armap %t.lib | \
+# RUN:   FileCheck %s --check-prefix=DOUBLE-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
+
+# DOUBLE-NAMES: [[PREFIX]]-universal.o
+
+# DOUBLE-SYMBOLS:      Archive map
+# DOUBLE-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-universal.o
+# DOUBLE-SYMBOLS-EMPTY:
+
+

diff  --git a/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-output.test b/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-output.test
new file mode 100644
index 000000000000..6a1305d2f97e
--- /dev/null
+++ b/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-output.test
@@ -0,0 +1,75 @@
+## This test checks that a correct universal binary is produced when
+## llvm-libtool-darwin is given bitcode for multiple architectures.
+
+## Check that the subtypes of cputype CPU_TYPE_ARM are stored in a fat file:
+# RUN: llvm-as %p/Inputs/arm64-ios.ll -o %t-arm64.bc
+# RUN: llvm-as %p/Inputs/armv7-ios.ll -o %t-armv7.bc
+
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-arm64.bc %t-armv7.bc
+
+## Check that architectures are present in the universal output:
+# RUN: llvm-lipo -info %t.lib | \
+# RUN:   FileCheck %s --check-prefix=ARCHS -DFILE=%t.lib
+
+# ARCHS: Architectures in the fat file: [[FILE]] are: armv7 arm64 
+
+## Check that the files with the same architecture are combined in an archive:
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-arm64.bc %t-arm64.bc %t-armv7.bc
+# RUN: llvm-lipo -info %t.lib | \
+# RUN:   FileCheck %s --check-prefix=ARCHS -DFILE=%t.lib
+# RUN: llvm-objdump --macho --arch all --all-headers %t.lib | \
+# RUN:   FileCheck %s --check-prefix=UNIVERSAL-MEMBERS -DFILE=%t.lib -DPREFIX=%basename_t.tmp --implicit-check-not=Archive
+
+# UNIVERSAL-MEMBERS:      Archive : [[FILE]] (architecture armv7)
+# UNIVERSAL-MEMBERS-NEXT: __.SYMDEF
+# UNIVERSAL-MEMBERS-NEXT: [[PREFIX]]-armv7.bc
+# UNIVERSAL-MEMBERS:      Archive : [[FILE]] (architecture arm64)
+# UNIVERSAL-MEMBERS-NEXT: __.SYMDEF
+# UNIVERSAL-MEMBERS-NEXT: [[PREFIX]]-arm64.bc
+# UNIVERSAL-MEMBERS-NEXT: [[PREFIX]]-arm64.bc
+
+## Check that the files extracted from a universal output are archives:
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-arm64.bc %t-armv7.bc
+# RUN: llvm-lipo %t.lib -thin armv7 -output %t-extracted-v7.a
+# RUN: llvm-ar t %t-extracted-v7.a | \
+# RUN:   FileCheck %s --check-prefix=EXTRACT --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
+# RUN: llvm-nm --print-armap %t-extracted-v7.a | \
+# RUN:   FileCheck %s --check-prefix=EXTRACT-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
+
+# EXTRACT: [[PREFIX]]-armv7.bc
+
+# EXTRACT-SYMBOLS:      Archive map
+# EXTRACT-SYMBOLS-NEXT: _armv7 in [[PREFIX]]-armv7.bc
+# EXTRACT-SYMBOLS-EMPTY:
+
+## Check that the subtypes of cputype CPU_TYPE_X86_64 are stored in a fat file:
+# RUN: llvm-as %p/Inputs/x86_64-osx.ll -o %t-x86_64.bc
+# RUN: llvm-as %p/Inputs/x86_64h-osx.ll -o %t-x86_64_h.bc
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-x86_64.bc %t-x86_64_h.bc
+# RUN: llvm-lipo -info %t.lib | \
+# RUN:   FileCheck %s --check-prefix=ARCHS-X86 -DFILE=%t.lib
+
+# ARCHS-X86: Architectures in the fat file: [[FILE]] are: x86_64 x86_64h
+
+## Check that the subtypes of cputype CPU_TYPE_ARM64 are stored in a fat file:
+## Testing it using llvm-objdump as, currently, there is no support for arm64e
+## under llvm/lib/Object/MachOObjectFile.cpp.
+# RUN: llvm-as %p/Inputs/arm64e-ios.ll -o %t-arm64e.bc
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-arm64.bc %t-arm64e.bc
+# RUN: llvm-objdump --macho --arch all --all-headers %t.lib | \
+# RUN:   FileCheck %s --check-prefix=UNIVERSAL-MEMBERS-ARM64 -DFILE=%t.lib -DPREFIX=%basename_t.tmp --implicit-check-not=Archive
+
+# UNIVERSAL-MEMBERS-ARM64:      Archive : [[FILE]] (architecture arm64)
+# UNIVERSAL-MEMBERS-ARM64-NEXT: __.SYMDEF
+# UNIVERSAL-MEMBERS-ARM64-NEXT: [[PREFIX]]-arm64.bc
+# UNIVERSAL-MEMBERS-ARM64:      Archive : [[FILE]]
+# UNIVERSAL-MEMBERS-ARM64-NEXT: __.SYMDEF
+# UNIVERSAL-MEMBERS-ARM64-NEXT: [[PREFIX]]-arm64e.bc
+
+## Check that 
diff erent cputypes are stored together in a fat file:
+# RUN: llvm-libtool-darwin -static -o %t.lib %t-armv7.bc %t-x86_64.bc
+# RUN: llvm-lipo -info %t.lib | \
+# RUN:   FileCheck %s --check-prefix=ARCHS-CPU -DFILE=%t.lib
+
+# ARCHS-CPU: Architectures in the fat file: [[FILE]] are: armv7 x86_64
+

diff  --git a/llvm/test/tools/llvm-libtool-darwin/universal-file-flattening.test b/llvm/test/tools/llvm-libtool-darwin/universal-object-flattening.test
similarity index 99%
rename from llvm/test/tools/llvm-libtool-darwin/universal-file-flattening.test
rename to llvm/test/tools/llvm-libtool-darwin/universal-object-flattening.test
index cd1dfc99858f..91aacc5932c2 100644
--- a/llvm/test/tools/llvm-libtool-darwin/universal-file-flattening.test
+++ b/llvm/test/tools/llvm-libtool-darwin/universal-object-flattening.test
@@ -1,4 +1,4 @@
-## This test checks that a universal file is flattened correctly.
+## This test checks that a universal object file is flattened correctly.
 
 # RUN: yaml2obj %s -o %t-universal.o
 # RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o

diff  --git a/llvm/test/tools/llvm-libtool-darwin/universal-output.test b/llvm/test/tools/llvm-libtool-darwin/universal-object-output.test
similarity index 98%
rename from llvm/test/tools/llvm-libtool-darwin/universal-output.test
rename to llvm/test/tools/llvm-libtool-darwin/universal-object-output.test
index 57d420bd3ebc..78fec8b7107c 100644
--- a/llvm/test/tools/llvm-libtool-darwin/universal-output.test
+++ b/llvm/test/tools/llvm-libtool-darwin/universal-object-output.test
@@ -1,5 +1,5 @@
 ## This test checks that a correct universal binary is produced when
-## llvm-libtool-darwin is given inputs for multiple architectures.
+## llvm-libtool-darwin is given object files for multiple architectures.
 
 ## Check that the subtypes of cputype CPU_TYPE_ARM are stored in a fat file:
 # RUN: yaml2obj %s -o %t.armv6 -DTYPE=0xC -DSUBTYPE=0x6 -DSTRING=_armv6

diff  --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
index 3a08d183c9ad..1ff6328ee6b6 100644
--- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
+++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
@@ -11,7 +11,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/BinaryFormat/Magic.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/Object/ArchiveWriter.h"
+#include "llvm/Object/IRObjectFile.h"
 #include "llvm/Object/MachO.h"
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/MachOUniversalWriter.h"
@@ -26,6 +28,8 @@
 using namespace llvm;
 using namespace llvm::object;
 
+static LLVMContext LLVMCtx;
+
 typedef std::map<uint64_t, std::vector<NewArchiveMember>>
     MembersPerArchitectureMap;
 
@@ -252,6 +256,38 @@ static Error verifyAndAddMachOObject(MembersPerArchitectureMap &Members,
   return Error::success();
 }
 
+static Error verifyAndAddIRObject(MembersPerArchitectureMap &Members,
+                                  NewArchiveMember Member, const Config &C) {
+  auto MBRef = Member.Buf->getMemBufferRef();
+  Expected<std::unique_ptr<object::IRObjectFile>> IROrErr =
+      object::IRObjectFile::create(MBRef, LLVMCtx);
+
+  // Throw error if not a valid IR object file.
+  if (!IROrErr)
+    return createFileError(Member.MemberName, IROrErr.takeError());
+
+  Triple TT = Triple(IROrErr->get()->getTargetTriple());
+
+  Expected<uint32_t> FileCPUTypeOrErr = MachO::getCPUType(TT);
+  if (!FileCPUTypeOrErr)
+    return FileCPUTypeOrErr.takeError();
+
+  Expected<uint32_t> FileCPUSubTypeOrErr = MachO::getCPUSubType(TT);
+  if (!FileCPUSubTypeOrErr)
+    return FileCPUSubTypeOrErr.takeError();
+
+  // If -arch_only is specified then skip this file if it doesn't match
+  // the architecture specified.
+  if (!ArchType.empty() &&
+      !acceptFileArch(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr, C)) {
+    return Error::success();
+  }
+
+  uint64_t FileCPUID = getCPUID(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr);
+  Members[FileCPUID].push_back(std::move(Member));
+  return Error::success();
+}
+
 static Error addChildMember(MembersPerArchitectureMap &Members,
                             const object::Archive::Child &M, const Config &C) {
   Expected<NewArchiveMember> NMOrErr =
@@ -259,6 +295,11 @@ static Error addChildMember(MembersPerArchitectureMap &Members,
   if (!NMOrErr)
     return NMOrErr.takeError();
 
+  file_magic Magic = identify_magic(NMOrErr->Buf->getBuffer());
+
+  if (Magic == file_magic::bitcode)
+    return verifyAndAddIRObject(Members, std::move(*NMOrErr), C);
+
   if (Error E = verifyAndAddMachOObject(Members, std::move(*NMOrErr), C))
     return E;
 
@@ -320,21 +361,41 @@ static Error addUniversalMembers(
       continue;
     }
 
+    Expected<std::unique_ptr<IRObjectFile>> IRObjectOrError =
+        O.getAsIRObject(LLVMCtx);
+    if (IRObjectOrError) {
+      // A universal file member can be a MachOObjectFile, an IRObject or an
+      // Archive. In case we can successfully cast the member as an IRObject, it
+      // is safe to throw away the error generated due to casting the object as
+      // a MachOObjectFile.
+      consumeError(MachOObjOrErr.takeError());
+
+      NewArchiveMember NewMember =
+          NewArchiveMember(IRObjectOrError->get()->getMemoryBufferRef());
+      NewMember.MemberName = sys::path::filename(NewMember.MemberName);
+
+      if (Error E = verifyAndAddIRObject(Members, std::move(NewMember), C))
+        return E;
+      continue;
+    }
+
     Expected<std::unique_ptr<Archive>> ArchiveOrError = O.getAsArchive();
     if (ArchiveOrError) {
-      // A universal file member can either be a MachOObjectFile or an Archive.
-      // In case we can successfully cast the member as an Archive, it is safe
-      // to throw away the error generated due to casting the object as a
-      // MachOObjectFile.
+      // A universal file member can be a MachOObjectFile, an IRObject or an
+      // Archive. In case we can successfully cast the member as an Archive, it
+      // is safe to throw away the error generated due to casting the object as
+      // a MachOObjectFile.
       consumeError(MachOObjOrErr.takeError());
+      consumeError(IRObjectOrError.takeError());
 
       if (Error E = processArchive(Members, **ArchiveOrError, FileName, C))
         return E;
       continue;
     }
 
-    Error CombinedError =
-        joinErrors(ArchiveOrError.takeError(), MachOObjOrErr.takeError());
+    Error CombinedError = joinErrors(
+        ArchiveOrError.takeError(),
+        joinErrors(IRObjectOrError.takeError(), MachOObjOrErr.takeError()));
     return createFileError(FileName, std::move(CombinedError));
   }
 
@@ -367,6 +428,10 @@ static Error addMember(MembersPerArchitectureMap &Members,
     return addUniversalMembers(Members, FileBuffers, std::move(*NMOrErr),
                                FileName, C);
 
+  // Bitcode files.
+  if (Magic == file_magic::bitcode)
+    return verifyAndAddIRObject(Members, std::move(*NMOrErr), C);
+
   if (Error E = verifyAndAddMachOObject(Members, std::move(*NMOrErr), C))
     return E;
   return Error::success();
@@ -378,7 +443,7 @@ buildSlices(ArrayRef<OwningBinary<Archive>> OutputBinaries) {
 
   for (const auto &OB : OutputBinaries) {
     const Archive &A = *OB.getBinary();
-    Expected<Slice> ArchiveSlice = Slice::create(A);
+    Expected<Slice> ArchiveSlice = Slice::create(A, &LLVMCtx);
     if (!ArchiveSlice)
       return ArchiveSlice.takeError();
     Slices.push_back(*ArchiveSlice);


        


More information about the llvm-commits mailing list