Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -8215,8 +8215,16 @@ // If the destination and first source operand are the same, and // there's no setting of the flags, use encoding T2 instead of T3. // Note that this is only for ADD, not SUB. This mirrors the system - // 'as' behaviour. Make sure the wide encoding wasn't explicit. - if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() || + // 'as' behaviour. Also take advantage of ADD being commutative. + // Make sure the wide encoding wasn't explicit. + bool Swap = false; + auto DestReg = Inst.getOperand(0).getReg(); + bool Transform = DestReg == Inst.getOperand(1).getReg(); + if (!Transform && DestReg == Inst.getOperand(2).getReg()) { + Transform = true; + Swap = true; + } + if (!Transform || Inst.getOperand(5).getReg() != 0 || (static_cast(*Operands[3]).isToken() && static_cast(*Operands[3]).getToken() == ".w")) @@ -8225,7 +8233,7 @@ TmpInst.setOpcode(ARM::tADDhirr); TmpInst.addOperand(Inst.getOperand(0)); TmpInst.addOperand(Inst.getOperand(0)); - TmpInst.addOperand(Inst.getOperand(2)); + TmpInst.addOperand(Inst.getOperand(Swap ? 1 : 2)); TmpInst.addOperand(Inst.getOperand(3)); TmpInst.addOperand(Inst.getOperand(4)); Inst = TmpInst; Index: test/MC/ARM/thumb2-narrow-dp.ll =================================================================== --- test/MC/ARM/thumb2-narrow-dp.ll +++ test/MC/ARM/thumb2-narrow-dp.ll @@ -44,6 +44,8 @@ // CHECK: adds r0, r2, r1 @ encoding: [0x50,0x18] ADDS r2, r2, r1 // ADDS has T1 narrow 3 operand // CHECK: adds r2, r2, r1 @ encoding: [0x52,0x18] + ADD r3, r1, r3 // T2 +// CHECK: add r3, r1 @ encoding: [0x0b,0x44] IT EQ // CHECK: it eq @ encoding: [0x08,0xbf]