106 lines · plain
1; This test checks if we can outline a singleton instance (i.e., an instance that2; does not repeat) through two codegen rounds. The first round identifies a local3; outlining instance within thin-two.ll, which is then encoded in the resulting4; object file and merged into the codegen data summary.5; The second round utilizes the merged codegen data to optimistically outline a6; singleton instance in thin-one.ll.7; Note that this global outlining creates a unique instance for each sequence8; without directly sharing identical functions for correctness.9; Actual code size reductions occur at link time through identical code folding.10; When both thinlto and lto modules are compiled, the lto module is processed11; independently, without relying on the merged codegen data. In this case,12; the identical code sequences are directly replaced by a common outlined function.13 14; RUN: split-file %s %t15 16; Verify each outlining instance is singleton with the global outlining for thinlto.17; They will be identical, which can be folded by the linker with ICF.18; RUN: opt -module-summary %t/thin-one.ll -o %t/thin-one.bc19; RUN: opt -module-summary %t/thin-two.ll -o %t/thin-two.bc20; RUN: llvm-lto2 run %t/thin-one.bc %t/thin-two.bc -o %t/thinlto \21; RUN: -r %t/thin-one.bc,_f3,px -r %t/thin-one.bc,_g,x \22; RUN: -r %t/thin-two.bc,_f1,px -r %t/thin-two.bc,_f2,px -r %t/thin-two.bc,_g,x \23; RUN: -codegen-data-thinlto-two-rounds24 25; thin-one.ll will have one outlining instance itself (matched in the global outlined hash tree)26; RUN: llvm-objdump -d %t/thinlto.1 | FileCheck %s --check-prefix=THINLTO-127; THINLTO-1: _OUTLINED_FUNCTION{{.*}}>:28; THINLTO-1-NEXT: mov29; THINLTO-1-NEXT: mov30; THINLTO-1-NEXT: b31 32; thin-two.ll will have two respective outlining instances (matched in the global outlined hash tree)33; RUN: llvm-objdump -d %t/thinlto.2 | FileCheck %s --check-prefix=THINLTO-234; THINLTO-2: _OUTLINED_FUNCTION{{.*}}>:35; THINLTO-2-NEXT: mov36; THINLTO-2-NEXT: mov37; THINLTO-2-NEXT: b38; THINLTO-2: _OUTLINED_FUNCTION{{.*}}>:39; THINLTO-2-NEXT: mov40; THINLTO-2-NEXT: mov41; THINLTO-2-NEXT: b42 43; Now add a lto module to the above thinlto modules.44; Verify the lto module is optimized independent of the global outlining for thinlto.45; RUN: opt %t/lto.ll -o %t/lto.bc46; RUN: llvm-lto2 run %t/thin-one.bc %t/thin-two.bc %t/lto.bc -o %t/out \47; RUN: -r %t/thin-one.bc,_f3,px -r %t/thin-one.bc,_g,x \48; RUN: -r %t/thin-two.bc,_f1,px -r %t/thin-two.bc,_f2,px -r %t/thin-two.bc,_g,x \49; RUN: -r %t/lto.bc,_f4,px -r %t/lto.bc,_f5,px -r %t/lto.bc,_f6,px -r %t/lto.bc,_g,x \50; RUN: -codegen-data-thinlto-two-rounds51 52; lto.ll will have one shared outlining instance within the lto module itself (no global outlining).53; RUN: llvm-objdump -d %t/out.0 | FileCheck %s --check-prefix=LTO-054; LTO-0: _OUTLINED_FUNCTION{{.*}}>:55; LTO-0-NEXT: mov56; LTO-0-NEXT: b57; LTO-0-NOT: _OUTLINED_FUNCTION{{.*}}>:58 59; thin-one.ll will have one outlining instance (matched in the global outlined hash tree)60; RUN: llvm-objdump -d %t/out.1 | FileCheck %s --check-prefix=THINLTO-161 62; thin-two.ll will have two outlining instances (matched in the global outlined hash tree)63; RUN: llvm-objdump -d %t/out.2 | FileCheck %s --check-prefix=THINLTO-264 65;--- thin-one.ll66target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"67target triple = "arm64-apple-darwin"68 69declare i32 @g(i32, i32, i32)70define i32 @f3() minsize {71 %1 = call i32 @g(i32 30, i32 1, i32 2);72 ret i32 %173}74 75;--- thin-two.ll76target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"77target triple = "arm64-apple-darwin"78 79declare i32 @g(i32, i32, i32)80define i32 @f1() minsize {81 %1 = call i32 @g(i32 10, i32 1, i32 2);82 ret i32 %183}84define i32 @f2() minsize {85 %1 = call i32 @g(i32 20, i32 1, i32 2);86 ret i32 %187}88 89;--- lto.ll90target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"91target triple = "arm64-apple-darwin"92 93declare i32 @g(i32, i32, i32)94define i32 @f4() minsize {95 %1 = call i32 @g(i32 10, i32 30, i32 2);96 ret i32 %197}98define i32 @f5() minsize {99 %1 = call i32 @g(i32 20, i32 40, i32 2);100 ret i32 %1101}102define i32 @f6() minsize {103 %1 = call i32 @g(i32 50, i32 60, i32 2);104 ret i32 %1105}106