[PATCH] D109041: [ARM] Fix assembly in `tInt_eh_sjlj_longjmp`

Tee KOBAYASHI via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 31 22:21:24 PDT 2021


xtkoba created this revision.
Herald added subscribers: hiraditya, kristof.beyls.
xtkoba requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

On Linux, it was made possible by https://reviews.llvm.org/D38253 that `__builtin_longjmp` can jump between ARM mode and Thumb mode. However, it has been revealed that it does not work in some cases. This is because in Thumb mode `__builtin_longjmp` emits an assembly instruction `ldr r11, [[BUFREG]]` which is misassembled by the integrated assembler, leading to `r11` (the frame pointer register in ARM mode) not being restored correctly.

The proposed change uses the instruction `mov r11, r7` in place of `ldr r11, [[BUFREG]]`. Following `ldr r7, [[BUFREG]]`, it should correctly restore `r11`.


https://reviews.llvm.org/D109041

Files:
  llvm/lib/Target/ARM/ARMAsmPrinter.cpp
  llvm/lib/Target/ARM/ARMInstrThumb.td
  llvm/test/CodeGen/ARM/setjmp_longjmp.ll


Index: llvm/test/CodeGen/ARM/setjmp_longjmp.ll
===================================================================
--- llvm/test/CodeGen/ARM/setjmp_longjmp.ll
+++ llvm/test/CodeGen/ARM/setjmp_longjmp.ll
@@ -1,5 +1,6 @@
 ; RUN: llc -simplifycfg-require-and-preserve-domtree=1 %s -o - | FileCheck %s
 ; RUN: llc -mtriple=armv7-linux -exception-model sjlj -simplifycfg-require-and-preserve-domtree=1 %s -o - | FileCheck %s -check-prefix CHECK-LINUX
+; RUN: llc -mtriple=thumbv7-linux -exception-model sjlj -simplifycfg-require-and-preserve-domtree=1 %s -o - | FileCheck %s -check-prefix CHECK-LINUX-THUMB2
 ; RUN: llc -mtriple=thumbv7-win32 -exception-model sjlj -simplifycfg-require-and-preserve-domtree=1 %s -o - | FileCheck %s -check-prefix CHECK-WIN32
 target triple = "armv7-apple-ios"
 
@@ -37,6 +38,13 @@
 ; CHECK-LINUX-NEXT: ldr r11, {{\[}}[[BUFREG]]{{\]}}
 ; CHECK-LINUX-NEXT: bx [[DESTREG]]
 
+; CHECK-LINUX-THUMB2: ldr [[DESTREG:r[0-9]+]], [{{\s*}}[[BUFREG:r[0-9]+]], #8]
+; CHECK-LINUX-THUMB2-NEXT: mov sp, [[DESTREG]]
+; CHECK-LINUX-THUMB2-NEXT: ldr [[DESTREG]], {{\[}}[[BUFREG]], #4]
+; CHECK-LINUX-THUMB2-NEXT: ldr r7, {{\[}}[[BUFREG]]{{\]}}
+; CHECK-LINUX-THUMB2-NEXT: mov r11, r7
+; CHECK-LINUX-THUMB2-NEXT: bx [[DESTREG]]
+
 ; CHECK-WIN32: ldr.w r11, [{{\s*}}[[BUFREG:r[0-9]+]]]
 ; CHECK-WIN32-NEXT: ldr.w sp, {{\[}}[[BUFREG]], #8]
 ; CHECK-WIN32-NEXT: ldr.w pc, {{\[}}[[BUFREG]], #4]
Index: llvm/lib/Target/ARM/ARMInstrThumb.td
===================================================================
--- llvm/lib/Target/ARM/ARMInstrThumb.td
+++ llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -1545,7 +1545,7 @@
 
 // FIXME: Non-IOS version(s)
 let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
-    Defs = [ R7, LR, SP ] in
+    Defs = [ R7, R11, LR, SP ] in
 def tInt_eh_sjlj_longjmp : XI<(outs), (ins tGPR:$src, tGPR:$scratch),
                               AddrModeNone, 0, IndexModeNone,
                               Pseudo, NoItinerary, "", "",
Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -2124,10 +2124,9 @@
         // Predicate.
         .addImm(ARMCC::AL)
         .addReg(0));
-      EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
+      EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
         .addReg(ARM::R11)
-        .addReg(SrcReg)
-        .addImm(0)
+        .addReg(ARM::R7)
         // Predicate.
         .addImm(ARMCC::AL)
         .addReg(0));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109041.369842.patch
Type: text/x-patch
Size: 2572 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210901/72c9de8f/attachment.bin>


More information about the llvm-commits mailing list