 +static ARMCC::CondCodes GetPredicate(MachineInstr &MI) {
 +  int PIdx = MI.findFirstPredOperandIdx();
 +  if (PIdx != -1) {
-+      return (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
++    return (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
 +  } else {
 +    return ARMCC::AL;
 +  }
 +}
 +
++void ARMSFIPlacement::getAnalysisUsage(AnalysisUsage &AU) const {
++  // Slight (possibly unnecessary) efficiency tweak:
++  // Promise not to modify the CFG.
++  AU.setPreservesCFG();
++  MachineFunctionPass::getAnalysisUsage(AU);
++}
++
++bool ARMSFIPlacement::TryPredicating(MachineInstr &MI, ARMCC::CondCodes Pred) {
++  // Can't predicate if it's already predicated.
++  // TODO(cbiffle): actually we can, if the conditions match.
++  if (TII->isPredicated(&MI)) return false;
++
++  /*
++   * ARM predicate operands use two actual MachineOperands: an immediate
++   * holding the predicate condition, and a register referencing the flags.
++   */
++  SmallVector<MachineOperand, 2> PredOperands;
++  PredOperands.push_back(MachineOperand::CreateImm((int64_t) Pred));
++  PredOperands.push_back(MachineOperand::CreateReg(ARM::CPSR, false));
++
++  // This attempts to rewrite, but some instructions can't be predicated.
++  return TII->PredicateInstruction(&MI, PredOperands);
++}
++
 +/*
-+ * Inserts a single BIC-based mask instruction immediately before the given
-+ * instruction/iterator position.
++ * Sandboxes a store instruction by inserting an appropriate mask or check
++ * operation before it.
 + */
-+void ARMSFIPlacement::InsertBicMask(MachineBasicBlock &MBB,
-+                                    MachineBasicBlock::iterator MBBI,
-+                                    MachineInstr &MI,
-+                                    int AddrOperand) {
-+  ARMCC::CondCodes Pred = GetPredicate(MI);
-+
-+  MachineOperand &Addr = MI.getOperand(AddrOperand);
-+
-+  BuildMI(MBB, MBBI, MI.getDebugLoc(),
-+          TII->get(ARM::SFISTRMASK))
-+    .addOperand(Addr)        // rD
-+    .addReg(0)               // apparently unused source register?
-+    .addImm((int64_t) Pred)  // predicate condition
-+    .addReg(ARM::CPSR);      // predicate source register (CPSR)
-+
-+  /*
-+   * This pseudo-instruction is intended to generate something resembling the
-+   * following, but with alignment enforced.
-+   * TODO(cbiffle): move alignment into this function, use the code below.
-+   *
-+   *  // bic<cc> Addr, Addr, #0xC0000000
-+   *  BuildMI(MBB, MBBI, MI.getDebugLoc(),
-+   *          TII->get(ARM::BICri))
-+   *    .addOperand(Addr)        // rD
-+   *    .addOperand(Addr)        // rN
-+   *    .addImm(0xC0000000)      // imm
-+   *    .addImm((int64_t) Pred)  // predicate condition
-+   *    .addReg(ARM::CPSR)       // predicate source register (CPSR)
-+   *    .addReg(0);              // flag output register (0 == no flags)
-+   */
++void ARMSFIPlacement::SandboxStore(MachineBasicBlock &MBB,
++                                   MachineBasicBlock::iterator MBBI,
++                                   MachineInstr &MI,
++                                   int AddrIdx,
++                                   bool CPSRLive) {
++  MachineOperand &Addr = MI.getOperand(AddrIdx);
++
++  if (!CPSRLive && TryPredicating(MI, ARMCC::EQ)) {
++    /*
++     * For unconditional stores where CPSR is not in use, we can use a faster
++     * sandboxing sequence by predicating the store -- assuming we *can*
++     * predicate the store.
++     */
++
++    // Instruction can be predicated -- use the new sandbox.
++    BuildMI(MBB, MBBI, MI.getDebugLoc(),
++            TII->get(ARM::SFISTRTST))
++      .addOperand(Addr)   // rD
++      .addReg(0);         // apparently unused source register?
++  } else {
++    // Use the older BIC sandbox, which is universal, but incurs a stall.
++    ARMCC::CondCodes Pred = GetPredicate(MI);
++    BuildMI(MBB, MBBI, MI.getDebugLoc(),
++            TII->get(ARM::SFISTRMASK))
++      .addOperand(Addr)        // rD
++      .addReg(0)               // apparently unused source register?
++      .addImm((int64_t) Pred)  // predicate condition
++      .addReg(ARM::CPSR);      // predicate source register (CPSR)
++
++    /*
++     * This pseudo-instruction is intended to generate something resembling the
++     * following, but with alignment enforced.
++     * TODO(cbiffle): move alignment into this function, use the code below.
++     *
++     *  // bic<cc> Addr, Addr, #0xC0000000
++     *  BuildMI(MBB, MBBI, MI.getDebugLoc(),
++     *          TII->get(ARM::BICri))
++     *    .addOperand(Addr)        // rD
++     *    .addOperand(Addr)        // rN
++     *    .addImm(0xC0000000)      // imm
++     *    .addImm((int64_t) Pred)  // predicate condition
++     *    .addReg(ARM::CPSR)       // predicate source register (CPSR)
++     *    .addReg(0);              // flag output register (0 == no flags)
++     */
++  }
 +}
 +
-+bool IsStoreRequiringMask(const MachineInstr &MI, int *AddrOperand) {
++static bool IsDangerousStore(const MachineInstr &MI, int *AddrIdx) {
 +  unsigned Opcode = MI.getOpcode();
 +  switch (Opcode) {
 +  default: return false;

 }
 
 //===----------------------------------------------------------------------===//
@@ -1519,4 +1878,3 @@
   TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
   TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
 }

 // ADD and SUB with 's' bit set.
 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
                           BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
@@ -1551,7 +1617,10 @@
 let isCall = 1,
   Defs = [R0, R12, LR, CPSR] in {
   def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
