diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -537,6 +537,24 @@ MachineOperand &PMO = MI.getOperand(PIdx); PMO.setImm(Pred[0].getImm()); MI.getOperand(PIdx+1).setReg(Pred[1].getReg()); + + // Thumb 1 arithmetic instructions do not set CPSR when executed inside an + // IT block. This affects how they are printed. + const MCInstrDesc &MCID = MI.getDesc(); + if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { + // Find the optional-def operand (cc_out). + unsigned OpNo; + for (OpNo = 0; + !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; + ++OpNo) + ; + assert(MCID.OpInfo[OpNo].isOptionalDef()); + assert((MI.getOperand(OpNo).isDead() || + MI.getOperand(OpNo).getReg() != ARM::CPSR) && + "if conversion tried to stop defining used CPSR"); + MI.getOperand(OpNo).setReg(ARM::NoRegister); + } + return true; } return false; diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td b/llvm/lib/Target/ARM/ARMInstrFormats.td --- a/llvm/lib/Target/ARM/ARMInstrFormats.td +++ b/llvm/lib/Target/ARM/ARMInstrFormats.td @@ -403,8 +403,9 @@ bit isUnaryDataProc = 0; bit canXformTo16Bit = 0; // The instruction is a 16-bit flag setting Thumb instruction. Used - // by the parser to determine whether to require the 'S' suffix on the - // mnemonic (when not in an IT block) or preclude it (when in an IT block). + // by the parser and if-converter to determine whether to require the 'S' + // suffix on the mnemonic (when not in an IT block) or preclude it (when + // in an IT block). bit thumbArithFlagSetting = 0; bit validForTailPredication = 0; diff --git a/llvm/test/CodeGen/Thumb2/ifcvt-rescan-diamonds.ll b/llvm/test/CodeGen/Thumb2/ifcvt-rescan-diamonds.ll --- a/llvm/test/CodeGen/Thumb2/ifcvt-rescan-diamonds.ll +++ b/llvm/test/CodeGen/Thumb2/ifcvt-rescan-diamonds.ll @@ -22,7 +22,8 @@ ; CHECK-NEXT: it eq ; CHECK-NEXT: ldreq ; CHECK-NEXT: it ne -; CHECK-NEXT: movsne + ; N.b. 16-bit mov instruction in IT block does not set flags. +; CHECK-NEXT: movne ; CHECK-NEXT: mvns ; CHECK-NEXT: b cond.true77: ; preds = %while.cond38