Index: test/MC/Mips/nacl-long-branch.ll |
diff --git a/test/MC/Mips/nacl-long-branch.ll b/test/MC/Mips/nacl-long-branch.ll |
new file mode 100644 |
index 0000000000000000000000000000000000000000..33ad41fcdc098a045c4d1d16022f16da6ee7af6e |
--- /dev/null |
+++ b/test/MC/Mips/nacl-long-branch.ll |
@@ -0,0 +1,89 @@ |
+; RUN: llc -filetype=obj -sfi-load -sfi-store -sfi-stack -sfi-branch -sfi-data \ |
+; RUN: -force-mips-long-branch -O3 -mtriple mipsel-none-nacl %s -o - \ |
+; RUN: | llvm-objdump -triple mipsel -disassemble -no-show-raw-insn - \ |
+; RUN: | FileCheck %s |
+ |
+; RUN: llc -filetype=obj -O3 -mtriple mipsel-none-nacl %s -o - \ |
+; RUN: | llvm-objdump -triple mipsel -disassemble -no-show-raw-insn - \ |
+; RUN: | FileCheck %s -check-prefix=CHECK-NOSFI |
+ |
+ |
+declare void @f() |
+ |
+define void @long_branch(i32 %arg) { |
+entry: |
+ %cmp = icmp eq i32 %arg, 0 |
+ br i1 %cmp, label %if.then, label %if.end |
+if.then: |
+ tail call void @f() |
+ br label %if.end |
+if.end: |
+ ret void |
+} |
+ |
+; This file tests that MipsLongBranchPass works with sandboxing. |
+; The nonsandboxed code of the previous function is: |
+ |
+; long_branch: |
+; CHECK-NOSFI: 0: lui $2, 0 |
+; CHECK-NOSFI: 4: addiu $2, $2, 0 |
+; CHECK-NOSFI: 8: addiu $sp, $sp, -24 |
+; CHECK-NOSFI: c: sw $ra, 20($sp) |
+; CHECK-NOSFI: 10: bne $4, $zero, 20 |
+; CHECK-NOSFI: 14: addu $gp, $2, $25 |
+; CHECK-NOSFI: 18: lw $25, 0($gp) |
+; CHECK-NOSFI: 1c: jalr $25 |
+; CHECK-NOSFI: 20: nop |
+; CHECK-NOSFI: 24: lw $ra, 20($sp) |
+; CHECK-NOSFI: 28: addiu $sp, $sp, 24 |
+; CHECK-NOSFI: 2c: jr $ra |
+; CHECK-NOSFI: 30: nop |
+ |
+; We pass -force-mips-long-branch option to llc to make sure that bne |
+; instruction is expanded into long branch. We specifically test that |
+; in the expanded sandboxed long branch sequence the offset that LUi/ADDiu |
+; instructions create is the correct offset from the ADDiu instruction to the |
+; branch target (which is lw $ra, 20($sp) in this case). More precisely: |
+; |
+; 0x80 - 0x40 = 64, |
+; where 0x40 and 0x80 are addresses and 64 is in the "addiu" at 0x40. |
+ |
+; 0: lui $2, 0 |
+; 4: addiu $2, $2, 0 |
+; 8: addiu $sp, $sp, -24 |
+; c: and $sp, $sp, $15 |
+; 10: sw $ra, 20($sp) |
+; 14: beq $4, $zero, 80 |
+; 18: addu $gp, $2, $25 |
+; 1c: nop |
+; 20: addiu $sp, $sp, -8 |
+; 24: and $sp, $sp, $15 |
+; 28: sw $ra, 0($sp) |
+; 2c: nop |
+; 30: nop |
+; 34: nop |
+; CHECK: 38: bal 8 |
+; CHECK-NEXT: 3c: lui $1, 0 |
+; CHECK-NEXT: 40: addiu $1, $1, 64 |
+; CHECK: addu $1, $ra, $1 |
+; CHECK: lw $ra, 0($sp) |
+; CHECK: nop |
+; CHECK: addiu $sp, $sp, 8 |
+; CHECK: and $sp, $sp, $15 |
+; CHECK: and $1, $1, $14 |
+; CHECK: jr $1 |
+; CHECK: nop |
+; 64: and $gp, $gp, $15 |
+; 68: lw $25, 0($gp) |
+; 6c: nop |
+; 70: nop |
+; 74: and $25, $25, $14 |
+; 78: jalr $25 |
+; 7c: nop |
+; CHECK: 80: lw $ra, 20($sp) |
+; 84: addiu $sp, $sp, 24 |
+; 88: and $sp, $sp, $15 |
+; 8c: nop |
+; 90: and $ra, $ra, $14 |
+; 94: jr $ra |
+; 98: nop |