diff --git a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp --- a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp +++ b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp @@ -322,13 +322,17 @@ default: return true; case M68kISD::SUB: - case ISD::SUB: { - SDNode *Dividend = U->getOperand(0).getNode(); - if (ConstantSDNode *CSDN = dyn_cast(Dividend)) - if (const uint64_t *RawData = CSDN->getAPIntValue().getRawData()) - if (0 == *RawData) - return false; - } + case ISD::SUB: + // Prefer NEG instruction when zero subtracts a value. + // e.g. + // move.l #0, %d0 + // sub.l (4,%sp), %d0 + // vs. + // move.l (4,%sp), %d0 + // neg.l %d0 + if (llvm::isNullConstant(U->getOperand(0))) + return false; + break; } } diff --git a/llvm/test/CodeGen/M68k/Arith/imul-neg.ll b/llvm/test/CodeGen/M68k/Arith/imul-neg.ll --- a/llvm/test/CodeGen/M68k/Arith/imul-neg.ll +++ b/llvm/test/CodeGen/M68k/Arith/imul-neg.ll @@ -1,6 +1,28 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=m68k-linux | FileCheck %s +define i8 @mul255_8(i8 %A) { +; CHECK-LABEL: mul255_8: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: move.b (7,%sp), %d0 +; CHECK-NEXT: neg.b %d0 +; CHECK-NEXT: rts + %mul = mul i8 %A, 255 + ret i8 %mul +} + +define i16 @mul65535_16(i16 %A) { +; CHECK-LABEL: mul65535_16: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: move.w (6,%sp), %d0 +; CHECK-NEXT: neg.w %d0 +; CHECK-NEXT: rts + %mul = mul i16 %A, 65535 + ret i16 %mul +} + define i32 @mul4294967295_32(i32 %A) { ; CHECK-LABEL: mul4294967295_32: ; CHECK: .cfi_startproc