Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[mips][micromips] fix filling delay slots for PseudoIndirectBranch_MM
Filling a delay slot in 32bit jump instructions with a 16bit instruction can cause issues. According to the documentation such an operation is unpredictable. This patch adds opcode Mips::PseudoIndirectBranch_MM alongside Mips::PseudoIndirectBranch and other instructions that are expanded to jr instruction and do not allow a 16bit instruction in their delay slots. Patch by Mirko Brkusanin. Differential Revision: https://reviews.llvm.org/D58507 llvm-svn: 354672
- Loading branch information
1 parent
3167b30
commit 6083106
Showing
2 changed files
with
69 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | ||
; RUN: llc -mtriple=mipsel-linux-gnu -mattr=+micromips -relocation-model=pic < %s | FileCheck %s | ||
|
||
; Test that the delay slot filler correctly handles indirect branches for | ||
; microMIPS in regard to incorrectly using 16bit instructions in delay slots of | ||
; 32bit instructions. | ||
|
||
define i32 @test(i32 signext %x, i32 signext %c) { | ||
; CHECK-LABEL: test: | ||
; CHECK: # %bb.0: # %entry | ||
; CHECK-NEXT: lui $2, %hi(_gp_disp) | ||
; CHECK-NEXT: addiu $2, $2, %lo(_gp_disp) | ||
; CHECK-NEXT: addiur2 $5, $5, -1 | ||
; CHECK-NEXT: sltiu $1, $5, 4 | ||
; CHECK-NEXT: beqz $1, $BB0_3 | ||
; CHECK-NEXT: addu $3, $2, $25 | ||
; CHECK-NEXT: $BB0_1: # %entry | ||
; CHECK-NEXT: li16 $2, 0 | ||
; CHECK-NEXT: sll16 $5, $5, 2 | ||
; CHECK-NEXT: lw $6, %got($JTI0_0)($3) | ||
; CHECK-NEXT: addu16 $5, $5, $6 | ||
; CHECK-NEXT: lw $5, %lo($JTI0_0)($5) | ||
; CHECK-NEXT: addu16 $3, $5, $3 | ||
; CHECK-NEXT: jr $3 | ||
; CHECK-NEXT: nop | ||
; CHECK-NEXT: $BB0_2: # %sw.bb2 | ||
; CHECK-NEXT: addiur2 $2, $4, 1 | ||
; CHECK-NEXT: jrc $ra | ||
; CHECK-NEXT: $BB0_3: | ||
; CHECK-NEXT: move $2, $4 | ||
; CHECK-NEXT: jrc $ra | ||
; CHECK-NEXT: $BB0_4: # %sw.bb3 | ||
; CHECK-NEXT: addius5 $4, 2 | ||
; CHECK-NEXT: move $2, $4 | ||
; CHECK-NEXT: jrc $ra | ||
; CHECK-NEXT: $BB0_5: # %sw.bb5 | ||
; CHECK-NEXT: addius5 $4, 3 | ||
; CHECK-NEXT: move $2, $4 | ||
; CHECK-NEXT: $BB0_6: # %for.cond.cleanup | ||
; CHECK-NEXT: jrc $ra | ||
entry: | ||
switch i32 %c, label %sw.epilog [ | ||
i32 4, label %sw.bb5 | ||
i32 1, label %for.cond.cleanup | ||
i32 2, label %sw.bb2 | ||
i32 3, label %sw.bb3 | ||
] | ||
|
||
sw.bb2: | ||
%add = add nsw i32 %x, 1 | ||
br label %sw.epilog | ||
|
||
sw.bb3: | ||
%add4 = add nsw i32 %x, 2 | ||
br label %sw.epilog | ||
|
||
sw.bb5: | ||
%add6 = add nsw i32 %x, 3 | ||
br label %sw.epilog | ||
|
||
sw.epilog: | ||
%a.0 = phi i32 [ %add6, %sw.bb5 ], [ %add4, %sw.bb3 ], [ %add, %sw.bb2 ], [ %x, %entry ] | ||
br label %for.cond.cleanup | ||
|
||
for.cond.cleanup: | ||
%a.028 = phi i32 [ %a.0, %sw.epilog ], [ 0, %entry ] | ||
ret i32 %a.028 | ||
} |