Skip to content

Miscompilation of calls to setjmp after "Preserve regmask when expanding the BLR_BTI pseudo instruction" #77915

@mstorsjo

Description

@mstorsjo

The fix to issue #73787, in commit 99d4859, from pull request #73927, seem to cause miscompilations in other similar-looking cases.

The issues can be triggered with ffmpeg, with the very latest versions of ffmpeg, that include commit FFmpeg/FFmpeg@6573969. To reproduce it, build it like this:

$ git clone https://github.com/ffmpeg/ffmpeg
$ cd ffmpeg
$ git checkout 65739691b90012c9d93b2e5e0e89a55d8de9eb7b
$ cd ..
$ mkdir ffmpeg-build
$ cd ffmpeg-build
$ ../ffmpeg/configure --cc=clang --extra-cflags='-mbranch-protection=standard' --extra-ldflags='-mbranch-protection=standard'
$ make -j$(nproc) fate-checkasm

The symptom is that when calling sigsetjmp, the first parameter, in register x0, has been lost and is passed as a null pointer.

The issue can be observed with this attached LLVM IR file as well, which is the code from tests/checkasm/idctdsp.c in such a build. idctdsp-ll.zip

It can be injected in such a build to test whether it is correctly compiled or not:

$ clang -mbranch-protection=standard -O3 idctdsp.ll -c -o tests/checkasm/idctdsp.o && make -j$(nproc) fate-checkasm-idctdsp

The difference in generated code can be observed by looking at the output of clang -mbranch-protection=standard -O3 idctdsp.ll -c -o tests/checkasm/idctdsp.o -mllvm -print-after-all before/after this change. That diff looks like this:

--- log-good    2024-01-12 14:24:33.730645287 +0200
+++ log-bad     2024-01-12 14:24:26.046612441 +0200
@@ -67330,8 +67330,8 @@
   renamable $x27 = LDRXroX killed renamable $x8, killed renamable $x9, 0, 0 :: (load (s64) from %ir.13, !tbaa !13)
   $x0 = ORRXrs $xzr, $fp, 0
   renamable $w1 = MOVZWi 1, 0
-  BUNDLE implicit-def $lr, implicit-def $w30, implicit $sp {
-    BL @__sigsetjmp, implicit-def $lr, implicit $sp
+  BUNDLE implicit-def $lr, implicit-def $w30, implicit-def $sp, implicit-def $wsp, implicit-def $w0, implicit $sp {
+    BL @__sigsetjmp, <regmask $fp $lr $wzr $xzr $b8 $b9 $b10 $b11 $b12 $b13 $b14 $b15 $d8 $d9 $d10 $d11 $d12 $d13 $d14 $d15 $h8 $h9 $h10 $h11 $h12 $h13 $h14 $h15 $s8 $s9 $s10 $s11 $s12 and 55 more...>, implicit-def $lr, implicit $sp, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0
     HINT 36
   }
   BL @checkasm_handle_signal, <regmask $fp $lr $wzr $xzr $b8 $b9 $b10 $b11 $b12 $b13 $b14 $b15 $d8 $d9 $d10 $d11 $d12 $d13 $d14 $d15 $h8 $h9 $h10 $h11 $h12 $h13 $h14 $h15 $s8 $s9 $s10 $s11 $s12 and 55 more...>, implicit-def dead $lr, implicit $sp, implicit $w0, implicit-def $sp, implicit-def dead $w0
@@ -73086,14 +73086,13 @@
   liveins: $fp, $x8, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x28
   $x9 = ADDXri $sp, 248, 0
   STRXui renamable $x8, $sp, 21 :: (store (s64) into %stack.16)
-  $x0 = ORRXrs $xzr, $fp, 0
   renamable $x19 = ADDXrs killed renamable $x9, killed renamable $x8, 4
   $x9 = ADDXri $sp, 296, 0
   renamable $w1 = MOVZWi 1, 0
   renamable $x8 = LDRXui renamable $x19, 1 :: (load (s64) from %ir.offset, !tbaa !7)
   renamable $x27 = LDRXroX killed renamable $x8, killed renamable $x9, 0, 0 :: (load (s64) from %ir.13, !tbaa !13)
-  BUNDLE implicit-def $lr, implicit-def $w30, implicit $sp {
-    BL @__sigsetjmp, implicit-def $lr, implicit $sp
+  BUNDLE implicit-def $lr, implicit-def $w30, implicit-def $sp, implicit-def $wsp, implicit-def $w0, implicit $sp {
+    BL @__sigsetjmp, <regmask $fp $lr $wzr $xzr $b8 $b9 $b10 $b11 $b12 $b13 $b14 $b15 $d8 $d9 $d10 $d11 $d12 $d13 $d14 $d15 $h8 $h9 $h10 $h11 $h12 $h13 $h14 $h15 $s8 $s9 $s10 $s11 $s12 and 55 more...>, implicit-def $lr, implicit $sp, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0
     HINT 36
   }
   BL @checkasm_handle_signal, <regmask $fp $lr $wzr $xzr $b8 $b9 $b10 $b11 $b12 $b13 $b14 $b15 $d8 $d9 $d10 $d11 $d12 $d13 $d14 $d15 $h8 $h9 $h10 $h11 $h12 $h13 $h14 $h15 $s8 $s9 $s10 $s11 $s12 and 55 more...>, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def dead $w0

(I left out a number of identical hunks of the diff.)

The first change is the one that looks like the right thing, the fix for #73787. However further on, this causes the $x0 = ORRXrs $xzr, $fp, 0, which is used as input to the __sigsetjmp call, gets lost.

CC @efriedma-quic @DavidSpickett

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions