Skip to content

Apple clang 15.0 miscompilation

Choose a tag to compare

Steps that are likely to reproduce the issue on my M2 Mac, with Apple Clang 15.0 installed:

  • Install plink 1.9 somewhere on the system PATH, either by downloading a binary from https://www.cog-genomics.org/plink/1.9/ , or following the compilation instructions in this repo.
  • Navigate to the 2.0/build_dynamic subdirectory.
  • Edit the right side of the "DEBUG=" line of the Makefile to have "-g".
  • Append "-DNO_UNALIGNED" to the right side of the first "BASEFLAGS" line. (Not strictly necessary, but rules out some possible causes.)
  • Make.
  • Navigate to the 2.0/Tests subdirectory.
  • Execute "./run_tests.sh ../build_dynamic" from there. You should get the following error: "./run_tests.sh: line 124: 12789 Segmentation fault: 11 $1/plink2 $2 $3 --bfile plink1_data --maf 0.02 --pheno pheno_qt.txt --glm allow-no-covars --out plink2_glm"

If necessary, I can provide the four input files for the failing command (plink1_data.bed, plink1_data.bim, plink1_data.fam, pheno_qt.txt) so the other test logic can be skipped.

The issue does not appear with Homebrew clang 16.0.6, or gcc 9.4.0 on Linux.

When I run under lldb, the segmentation fault is attributed to line 1224 of plink2_glm_linear.cc . But if I try to evaluate the supposedly problematic "xtx_inv[pred_uidx * (cur_predictor_ct + 1)]" expression in lldb after the crash, it has the value I was expecting. I tried setting a breakpoint at line 1223 while appending "--threads 1" to the plink2 command line, and then single-stepping through the assembly instructions until the crash; I observed that the assembly code thinks xtx_inv is at a slightly different address than lldb does, loads garbage from its address, and triggers a crash on dereference. The exact garbage can vary.

(update, 9 Oct 2023: this miscompilation does not happen with Xcode 15.1 beta, and there is now a test in the main branch that is likely to catch a recurrence of the issue.)