Index: lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp +++ lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp @@ -137,18 +137,17 @@ &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) + if (MaskBefore || MaskAfter) { + if (PendingCall) + report_fatal_error("Dangerous instruction in branch delay slot!"); sandboxLoadStoreStackChange(Inst, AddrIdx, STI, MaskBefore, MaskAfter); - else - MipsELFStreamer::EmitInstruction(Inst, STI); - return; + return; + } + // fallthrough } // Sandbox calls by aligning call and branch delay to the bundle end. 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)