From: Petar Jovanovic Date: Fri, 22 Feb 2019 14:53:58 +0000 (+0000) Subject: [mips][micromips] fix filling delay slots for PseudoIndirectBranch_MM X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6083106b1216566f189ecb6e0ae0340b61c4254a;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp index 7f61956..a05c387 100644 --- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -725,6 +725,7 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin, // but we don't have enough information to make that decision. if (InMicroMipsMode && TII->getInstSizeInBytes(*CurrI) == 2 && (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch || + Opcode == Mips::PseudoIndirectBranch_MM || Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL)) continue; // Instructions LWP/SWP and MOVEP should not be in a delay slot as that diff --git a/llvm/test/CodeGen/Mips/pseudo-jump-fill.ll b/llvm/test/CodeGen/Mips/pseudo-jump-fill.ll new file mode 100644 index 0000000..31f077d --- /dev/null +++ b/llvm/test/CodeGen/Mips/pseudo-jump-fill.ll @@ -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 +}