<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/109929>109929</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[ARM] musttail attribute fails with LTO and mismatched -ffast-math options
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:ARM,
crash-on-valid
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ostannard
</td>
</tr>
</table>
<pre>
This code causes an error in the ARM backend when built with LTO, and one part is build with -ffast-math, and the other with UBSan:
```c
struct function_pointers {
double (*F95)(void);
};
void init_0(struct function_pointers *p);
double F93(void);
#ifdef PART1
struct function_pointers actual_fptrs;
[[clang::noinline]] double F90(void) {
[[clang::musttail]] return F93();
}
double F95(void) { return 0.0; }
signed int main(void) {
actual_fptrs.F95 = &F95;
init_0(&actual_fptrs);
F90();
return 0;
}
#endif
#ifdef PART2
static struct function_pointers *fptrs;
void init_0(struct function_pointers *p) { fptrs = p; }
double F93(void) {
[[clang::musttail]] return fptrs->F95();
}
#endif
```
```sh
#!/bin/bash -xe
/work/llvm/install/bin/clang --target=arm-none-eabi -march=armv7-a -c test.c -o part1.bc -O1 -flto -DPART1 -ffast-math
/work/llvm/install/bin/clang --target=arm-none-eabi -march=armv7-a -c test.c -o part2.bc -O1 -flto -DPART2 -fsanitize=undefined -fsanitize-trap=undefined
/work/llvm/install/bin/llvm-lto2 run part1.bc part2.bc -o test.o \
-r part1.bc,F90,pl \
-r part1.bc,F93,l \
-r part1.bc,F95,pl \
-r part1.bc,main,px \
-r part1.bc,init_0,l \
-r part1.bc,actual_fptrs,pl \
-r part2.bc,init_0,pl \
-r part2.bc,F93,pl
```
```
$ ./run.sh
+ /work/llvm/install/bin/clang --target=arm-none-eabi -march=armv7-a -c test.c -o part1.bc -O1 -flto -DPART1 -ffast-math
+ /work/llvm/install/bin/clang --target=arm-none-eabi -march=armv7-a -c test.c -o part2.bc -O1 -flto -DPART2 -fsanitize=undefined -fsanitize-trap=undefined
+ /work/llvm/install/bin/llvm-lto2 run part1.bc part2.bc -o test.o -r part1.bc,F90,pl -r part1.bc,F93,l -r part1.bc,F95,pl -r part1.bc,main,px -r part1.bc,init_0,l -r part1.bc,actual_fptrs,pl -r part2.bc,init_0,pl -r part2.bc,F93,pl
LLVM ERROR: failed to perform tail call elimination on a call site marked musttail
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: /work/llvm/install/bin/llvm-lto2 /work/llvm/install/bin/llvm-lto2 part1.bc part2.bc -o test.o -r part1.bc,F90,pl -r part1.bc,F93,l -r part1.bc,F95,pl -r part1.bc,main,px -r part1.bc,init_0,l -r part1.bc,actual_fptrs,pl -r part2.bc,init_0,pl -r part2.bc,F93,pl
1. Running pass 'Function Pass Manager' on module 'ld-temp.o'.
2. Running pass 'ARM Instruction Selection' on function '@F90'
#0 0x00005566b41c38a7 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/work/llvm/install/bin/llvm-lto2+0x64158a7)
#1 0x00005566b41c148e llvm::sys::RunSignalHandlers() (/work/llvm/install/bin/llvm-lto2+0x641348e)
#2 0x00005566b41c3f7a SignalHandler(int) Signals.cpp:0:0
#3 0x00007f1223242520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
#4 0x00007f12232969fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
#5 0x00007f12232969fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
#6 0x00007f12232969fc pthread_kill ./nptl/pthread_kill.c:89:10
#7 0x00007f1223242476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
#8 0x00007f12232287f3 abort ./stdlib/abort.c:81:7
#9 0x00005566b4123733 llvm::report_fatal_error(llvm::Twine const&, bool) (/work/llvm/install/bin/llvm-lto2+0x6375733)
#10 0x00005566b4123586 (/work/llvm/install/bin/llvm-lto2+0x6375586)
#11 0x00005566b26d48c6 llvm::ARMTargetLowering::LowerCall(llvm::TargetLowering::CallLoweringInfo&, llvm::SmallVectorImpl<llvm::SDValue>&) const ARMISelLowering.cpp:0:0
#12 0x00005566b44ef594 llvm::TargetLowering::LowerCallTo(llvm::TargetLowering::CallLoweringInfo&) const (/work/llvm/install/bin/llvm-lto2+0x6741594)
#13 0x00005566b45108e2 llvm::SelectionDAGBuilder::lowerInvokable(llvm::TargetLowering::CallLoweringInfo&, llvm::BasicBlock const*) (/work/llvm/install/bin/llvm-lto2+0x67628e2)
#14 0x00005566b44f7cd5 llvm::SelectionDAGBuilder::LowerCallTo(llvm::CallBase const&, llvm::SDValue, bool, bool, llvm::BasicBlock const*, llvm::TargetLowering::PtrAuthInfo const*) (/work/llvm/install/bin/llvm-lto2+0x6749cd5)
#15 0x00005566b44e0a0e llvm::SelectionDAGBuilder::visitCall(llvm::CallInst const&) (/work/llvm/install/bin/llvm-lto2+0x6732a0e)
#16 0x00005566b44d363c llvm::SelectionDAGBuilder::visit(llvm::Instruction const&) (/work/llvm/install/bin/llvm-lto2+0x672563c)
#17 0x00005566b45926c6 llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void, true, llvm::BasicBlock>, false, true>, llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void, true, llvm::BasicBlock>, false, true>, bool&) (/work/llvm/install/bin/llvm-lto2+0x67e46c6)
#18 0x00005566b4591e3c llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/work/llvm/install/bin/llvm-lto2+0x67e3e3c)
#19 0x00005566b458f132 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/work/llvm/install/bin/llvm-lto2+0x67e1132)
#20 0x00005566b27dfbc1 (anonymous namespace)::ARMDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) ARMISelDAGToDAG.cpp:0:0
#21 0x00005566b458ca46 llvm::SelectionDAGISelLegacy::runOnMachineFunction(llvm::MachineFunction&) (/work/llvm/install/bin/llvm-lto2+0x67dea46)
#22 0x00005566b37c20d4 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/work/llvm/install/bin/llvm-lto2+0x5a140d4)
#23 0x00005566b3d30999 llvm::FPPassManager::runOnFunction(llvm::Function&) (/work/llvm/install/bin/llvm-lto2+0x5f82999)
#24 0x00005566b3d38791 llvm::FPPassManager::runOnModule(llvm::Module&) (/work/llvm/install/bin/llvm-lto2+0x5f8a791)
#25 0x00005566b3d3141f llvm::legacy::PassManagerImpl::run(llvm::Module&) (/work/llvm/install/bin/llvm-lto2+0x5f8341f)
#26 0x00005566b3e14659 codegen(llvm::lto::Config const&, llvm::TargetMachine*, std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream, std::default_delete<llvm::CachedFileStream>>> (unsigned int, llvm::Twine const&)>, unsigned int, llvm::Module&, llvm::ModuleSummaryIndex const&) LTOBackend.cpp:0:0
#27 0x00005566b3e134da llvm::lto::backend(llvm::lto::Config const&, std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream, std::default_delete<llvm::CachedFileStream>>> (unsigned int, llvm::Twine const&)>, unsigned int, llvm::Module&, llvm::ModuleSummaryIndex&) (/work/llvm/install/bin/llvm-lto2+0x60654da)
#28 0x00005566b3df5547 llvm::lto::LTO::runRegularLTO(std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream, std::default_delete<llvm::CachedFileStream>>> (unsigned int, llvm::Twine const&)>) (/work/llvm/install/bin/llvm-lto2+0x6047547)
#29 0x00005566b3df4aea llvm::lto::LTO::run(std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream, std::default_delete<llvm::CachedFileStream>>> (unsigned int, llvm::Twine const&)>, std::function<llvm::Expected<std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream, std::default_delete<llvm::CachedFileStream>>> (unsigned int, llvm::Twine const&)>> (unsigned int, llvm::StringRef, llvm::Twine const&)>) (/work/llvm/install/bin/llvm-lto2+0x6046aea)
#30 0x00005566b1e07cf3 run(int, char**) llvm-lto2.cpp:0:0
#31 0x00005566b1e02644 main (/work/llvm/install/bin/llvm-lto2+0x4054644)
#32 0x00007f1223229d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#33 0x00007f1223229e40 call_init ./csu/../csu/libc-start.c:128:20
#34 0x00007f1223229e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#35 0x00005566b1dfed25 _start (/work/llvm/install/bin/llvm-lto2+0x4050d25)
./run.sh: line 13: 1466542 Aborted (core dumped) /work/llvm/install/bin/llvm-lto2 run part1.bc part2.bc -o test.o -r part1.bc,F90,pl -r part1.bc,F93,l -r part1.bc,F95,pl -r part1.bc,main,px -r part1.bc,init_0,l -r part1.bc,actual_fptrs,pl -r part2.bc,init_0,pl -r part2.bc,F93,pl
```
I think what's causing this to fail is that, going into the backend, `@F90` has a `nofpclass(nan inf)` attribute on its return value, but has a `musttail` call without that attribute. Removing the attribute from `@F90` or adding it to the call site causes the compile to succeed.
```
define internal nofpclass(nan inf) double @F90() unnamed_addr #0 {
entry:
%0 = load ptr, ptr @fptrs, align 4, !tbaa !6
%1 = icmp ne ptr %0, null, !nosanitize !10
%2 = ptrtoint ptr %0 to i32, !nosanitize !10
%3 = and i32 %2, 3, !nosanitize !10
%4 = icmp eq i32 %3, 0, !nosanitize !10
%5 = and i1 %1, %4, !nosanitize !10
br i1 %5, label %cont1.i, label %trap.i, !nosanitize !10
trap.i: ; preds = %entry
tail call void @llvm.ubsantrap(i8 22) #4, !nosanitize !10
unreachable, !nosanitize !10
cont1.i: ; preds = %entry
%6 = load ptr, ptr @actual_fptrs, align 4, !tbaa !11
%7 = ptrtoint ptr %6 to i32, !nosanitize !10
%8 = and i32 %7, -2, !nosanitize !10
%9 = inttoptr i32 %8 to ptr, !nosanitize !10
%10 = getelementptr i8, ptr %9, i32 -8
%11 = load i32, ptr %10, align 4, !nosanitize !10
%12 = icmp eq i32 %11, -1056584962, !nosanitize !10
br i1 %12, label %typecheck.i, label %cont4.i, !nosanitize !10
typecheck.i: ; preds = %cont1.i
%13 = getelementptr i8, ptr %9, i32 -4
%14 = load i32, ptr %13, align 4, !nosanitize !10
%15 = icmp eq i32 %14, -166727886, !nosanitize !10
br i1 %15, label %cont4.i, label %trap2.i, !nosanitize !10
trap2.i: ; preds = %typecheck.i
tail call void @llvm.ubsantrap(i8 6) #4, !nosanitize !10
unreachable, !nosanitize !10
cont4.i: ; preds = %typecheck.i, %cont1.i
%call.i = musttail call double %6() #5
ret double %call.i
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsW19z4ygS_zTkhbJLAvTvIQ-OM96bqkzNVJLbVxeWkM0FgRahJHOf_goky8KRE49nd-tub1MziYLp5kf3r5sWENo0fCsZuwbRDYhur2hrdkpfq8ZQKakurjaq-H79uOMNzFXBYE7bhjWQSsi0VhpyCc2OwcX9F7ih-ROTBXzZMQk3LRcGvnCzg3ePXwFaQioLqCSDNdUG8sb1KLoes7KkjZlV1Oz2Pa1SZXZMdz3-efNAJcALENyCYAHioPuXd783Rre5gWUrc8OVXNeKS8N0A0Fy0_WAsFDtRjAIUArQYpVFAGUApc-KF_YJ9_1Acnt4dt9tD8glN-sAoPT0SGhRe4rc937QVYanxuq-I8zLgpXw2-L-MfxgPjQ3LRXrsja6OdZj_XeTCyq31k54IRWXgksGolsQ3cIBSnCAMrbPG_mqbYyhXPTymplWy34qxyabmnLkj7NXEMwDgG_gkZQjobWzgRXlchriePbzVRZBgG8hQLEdCw-9Bl8BFHv2GmGGvR3eugMOOCcmiDCTBS9Pug_t3UcNz-F7XJny4I8xzdnUqXFmqCeMOsW-C1zuBpkB_Knz6bTvfdPs49Oz1L6x2Q0yAIUArTbW4asNbXZw9sp8665elH4CaCXEcwXQisvGUCEGIQcezmaG6i0zAN9SXc2kkmzG6IbDWUV1vuuan5MZhbMcGtaYeQ5nymWicL7J4exrCGelMArObl0YehnpT0KCppAgOCsbKrnh_2YA37ayYCW3kXJonhlN6_FnZwK2zTNhFIK6lQdbHKCoDqCCIFruKTPTQ0-Ali6IlrV4rwcGaPluh-gDFV0-WNavp7vsg-a9gfxUMD0iOlL3XqduZrU4h_F7jxA4B2ilWzlvdnDfeAP_m1j-Z6D53Zl-Bujz2X6C4tO8PkHmUww-SduPuHqaoO-x8u7u1y_w0_3913uAF7CkXLACGgVrpkulK2hzPcypEJAJXnFJ7UoDlYS0a224YbCi-okVcFgbnOZvd58WD59g024qbiCFm3YLNauVNlb_zpi6sUsKWgG02nKzazfzXFUH9zh31Fr9i-XGeqtpWtYAtHK1H5e5aAvmasBc22XBlpZG05zNu-EfDM2fYNFW9VATBnPovr5ptdW0glRv24pJY3H8CD1-oOv_CYvC3rL3rZRcbmFNG1uFJKu-NIHfbMMXKumWaYASS6BKFa2rthNRzAyr6rkCKOm9h04otC8Rn2VX-Fi9D0ww99Qr3ddCti8ggTNq0mdngHAAg9cgCIIoiuMNCXOc0gQ6J7ripvnedA_fNJfGMejRUgqg9NBJ05e1aoxmtAIoti8jXBpXNtnC51xmAHQTvMYkjFKa2HJpgBgeQQxJyqYg3rfygW8lFf-gshDM-i-9GAUmKfNQoGNDlQmF3ngApf28u-Zmntc21AL3f1CEe0VJGSKEEUERCnqMgm8AWr2m8TomM8Fl-zrbyrb7IJ83ah47eE7EA0d8nVmclTlcr2uz04wW6ycuxJpXtWA2uLuEZRdVWRtrgnG3eQ7wghCAF0l80B-do99W2pKKdzUnKcCLcGSNeErzWOxddWl2pC45Ni5JYrhtnD-cpu4RoNXc_fa9KVhtc2itGv5q6wzKG-Z0owTgxcgGqa8apUmJId3Y7O1UmaJzn2vq0IV2xgcNmU8hhBOMR0TuloJ1SQ0Va7dR4EXZ4wuXDOZKNqaPso1S4kKC4yRKMB44ZKMsOEYXpfGFqqM09lR7EYzigqR5PJr44v7LoyuL7tQL03z_YuV-W7qRxmaY6Gk77Vs-y1L19jkIPVRUiF9ZbpT-XNUC4OXos9tfqWgZwJ-cWNaZGC7uv3x-YIPat7FsJ-YnBcLKKCPwfazDrB7VZfPaA7zANQkJo4x4rsHeDKIwSBkaG26_mtwufrlpuSiY7j4QFtZn-aye6Eawn_fQDW14fiNU_rSn-OJCaicxShnyJkl8N5VJXkTnTPKUr2zTDW38aHzLqCFEDz8_mPDyA_J8M3rRmp214E-biWR5EXlmio7YHNCAnWOmZ95w8yZQbYMtTEZGugwoRjRgHtDYB1rgGOdnA_VAjiunn8WJohjnHs7ED64MxV7eG-O0uWbceqCHh5cL3pg1N0xTo_T6Zb3htlhfHvcomHvt6Pc0C7ZWtR3I7zqavKWe0R1nSyoa99Dtfh0-mCKvS5sjGde3a_vfRN1F6sUkYCTO_cUvPSJByE6S9ZgEC5dmesyNR4ThPeJnWcswO2KtX6ZEaRniU0vCAbBu5Vf5heY7Ltkemwf4zWeXIw5D7OV35JUuKCnKTR5a1VQq-b1SbQMlrVhTuxeXbCg6bhe_PKrfYxZ9rbDXN1kroPDIrDkl7yWDO7al-fc_3bgFo8TjL_JqHJzkKCjGNc7R0Pa1dgR6Eu1Pw4xoSILCK2SQV8jgAgdZlo1grr5ZZPv37T8cYJmiLMs8gOQIYJpk4RkAv7hNAd_bfdPl4GiShR646AhcSMJyBE6MyDiC2dXSPdTfGSImYelB9BZ9zEISR5k7Xt0yf2xhVF-BKFny7YkirSuvevb2xVdjiu7D_aaJt_B8eq1ZblgB8HLo2Er-W8vWtdFe1yXNd6xYccEe-m2RkfKClbQVdrUTzLD35fCn7p-1YSsPB35Hczl6Ncz6tey0xMg_b5sf2qqi-vtnWbBXb325e_x6051XT6e45MhFmBQUTjimP_Q-22t_--WNXy5P8UEckYJ6oZX60V9GEUmm_Hb3-HUI93u2bQXV7p5C-tdy0GVmJUlEEs-s2ZFZCWWT4TA261_OmJdE719h4h8JPRj7Wn_Pyj-QkTFlXqD7u_0hC5K8xLBjXQ8w31HtVkO3rzBonMz3_s58yAIUE-KuolwAlwQRiYlX0w177vst16zIArheC77J142h2qxzKsTajTgHaJU37dud3X7veEpovgN4Ebkt6fgwKj4elZHAHe2tueTmeKDu0WqfOe1u5zdEVikamYpMKfWmMjWLSeU4sa8w0UG3V7yFRckKFMFO62WOCAp02Bk6nL4DvIDC0jPE9jEkcRwRBBcbpQ0r4PEXQGmuNHMnjqy7RvP3gfO51yA-Q7Pj8gm-7KgBKGncHUIut7a5gUa5g2loH12HJdwq-ymXRrkj4KHEWkKruTv4iwO4ow2ktkmqss6FfVtDqaQScunK7TiA1BjNN61hUEnITbO_0vQ8bGq25qBnOOKOuyBxVw9Vaxywg645vGeVeu5mwEZjlFpVPkSlIS0KNxt3MO5OtIeT9f4upWtUVc0Fs32aNs8ZK-bv3CTprj_A4Zhq2gDDlcf-qNSdILZS0ooVa1oUujs0HS6EMWm0ezHaXw9DUeDulglFC2gXJrS0P6zCPVMgFXwrIXHOQaHZUGp_xiMdodPB86qGknXyKLJcgrIVoheUan_Jw_42HIPZrqi732a0UVyaQYE1FcfoY3ns5N29AoycQiuDPxYkB-Dst72wkws-Fo4Oo4bOCp1IRD4Q3eheIHKLKd0wYX_LlTThnHttRtO6azqpr_ved8SLN3nt9BfAN7DWrGj6S5ZRx44e5eHiiLu0CEhg09283TRUuks6KOUpRKjLlPiDSbdSM5rvutOXD2ezNwVefAASoCg-xd-jhHeCxmE40pVM8jA-m4fpMQ8TKzM7QzLriCiNUXbUXjx1N3m6WZ2Wt9TronjLDOtOzZ2SdLAGijJ30QEjOEvHgRserNfPsO8fBm9t9g7-EE1FUuhCYhYGURylJIs_MsQQGSHyw-B7zfIdy5-OwsPyhJwXHyMN5wbJG-rtaTmaNj7f7mQsR07aHf-Y3aNJu5PO7nGcoCRN47PN_jYjkYmMhM5OSegHc9Ibk4_99kOJKT4vL12QmMiJxHRE0km-WNhz7iT2lUg3leFPF6J4uAeEo9F99VGPTsnx7ex9-XBVXOMiwxm9YtdhghIUEYLCq901zUkUpQSnQRrHrKQZo5sIs02IaJgWJLri1yhAJMhQFKQRJuG8pBtclCyLoxhvMKOABKyiXMydwZXeXrlLfddhkGUou3IcadxfmSC0r-jc0QWwy8QSIOSu-s2UnD1TwQvbHN1e6WtXSG_abWOdyRvTHEYw3Aj3lytWTTQy26gmo1w0w9-huPRb8aaixr4ejy_Awv6A7qrV4vryC4z9dJ-v0X8CAAD__24nOxw">