Index: lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp +++ lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp @@ -130,27 +130,6 @@ return; } - // Sandbox loads, stores and SP changes. - unsigned AddrIdx; - bool IsStore; - bool IsMemAccess = isBasePlusOffsetMemoryAccess(Inst.getOpcode(), &AddrIdx, - &IsStore); - bool IsSPFirstOperand = isStackPointerFirstOperand(Inst); - if (IsMemAccess || IsSPFirstOperand) { - if (PendingCall) - report_fatal_error("Dangerous instruction in branch delay slot!"); - - bool MaskBefore = (IsMemAccess - && baseRegNeedsLoadStoreMask(Inst.getOperand(AddrIdx) - .getReg())); - bool MaskAfter = IsSPFirstOperand && !IsStore; - if (MaskBefore || MaskAfter) - sandboxLoadStoreStackChange(Inst, AddrIdx, STI, MaskBefore, MaskAfter); - else - MipsELFStreamer::EmitInstruction(Inst, STI); - return; - } - // Sandbox calls by aligning call and branch delay to the bundle end. // For indirect calls, emit the mask before the call. bool IsIndirectCall; @@ -168,6 +147,27 @@ PendingCall = true; return; } + + // Sandbox loads, stores and SP changes. + unsigned AddrIdx; + bool IsStore; + bool IsMemAccess = isBasePlusOffsetMemoryAccess(Inst.getOpcode(), &AddrIdx, + &IsStore); + bool IsSPFirstOperand = isStackPointerFirstOperand(Inst); + if (IsMemAccess || IsSPFirstOperand) { + bool MaskBefore = (IsMemAccess + && baseRegNeedsLoadStoreMask(Inst.getOperand(AddrIdx) + .getReg())); + bool MaskAfter = IsSPFirstOperand && !IsStore; + if (MaskBefore || MaskAfter) { + if (PendingCall) + report_fatal_error("Dangerous instruction in branch delay slot!"); + sandboxLoadStoreStackChange(Inst, AddrIdx, STI, MaskBefore, MaskAfter); + return; + } + // fallthrough + } + if (PendingCall) { // Finish the sandboxing sequence by emitting branch delay. MipsELFStreamer::EmitInstruction(Inst, STI); Index: test/MC/Mips/nacl-mask.s =================================================================== --- test/MC/Mips/nacl-mask.s +++ test/MC/Mips/nacl-mask.s @@ -283,3 +283,31 @@ # CHECK-NEXT: and $25, $25, $14 # CHECK-NEXT: jalr $25 # CHECK-NEXT: addiu $4, $zero, 5 + + + +# Test that we can put non-dangerous loads and stores in branch delay slot. + + .align 4 +test6: + .set noreorder + + jal func1 + sw $4, 0($sp) + + bal func2 + lw $5, 0($t8) + + jalr $t9 + sw $sp, 0($sp) + +# CHECK-LABEL: test6: + +# CHECK: jal +# CHECK-NEXT: sw $4, 0($sp) + +# CHECK: bal +# CHECK-NEXT: lw $5, 0($24) + +# CHECK: jalr +# CHECK-NEXT: sw $sp, 0($sp)