[llvm] 78b16cc - [M68k] Instruction selection to choose neg x when mul x -1 (Fix issue 48588)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 2 22:20:48 PDT 2022


Author: Douglas Chen
Date: 2022-06-03T13:20:30+08:00
New Revision: 78b16ccf2b5c4ba4ebd7f1e2a2fc1dcad0e1a343

URL: https://github.com/llvm/llvm-project/commit/78b16ccf2b5c4ba4ebd7f1e2a2fc1dcad0e1a343
DIFF: https://github.com/llvm/llvm-project/commit/78b16ccf2b5c4ba4ebd7f1e2a2fc1dcad0e1a343.diff

LOG: [M68k] Instruction selection to choose neg x when mul x -1 (Fix issue 48588)

This patch is trying to fix issue 48588(https://github.com/llvm/llvm-project/issues/48588)

I found the results of Instruction Selection between SelectionDAG and FastISEL for the `%mul = mul i32 %A, 4294967295`:
(seldag-isel) mul --> sub --> SUB32dp
(fast-isel)   mul --> sub --> NEG32d

My patch to fix this issue is by overriding a virtual function M68kDAGToDAGISel::IsProfitableToFold(). Return `false` when it was trying to match with SUB, then it will match with NEG.

Reviewed By: myhsu

Differential Revision: https://reviews.llvm.org/D116886

Added: 
    

Modified: 
    llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
    llvm/test/CodeGen/M68k/Arith/imul-neg.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
index b75fbc3c7f220..f9459e284aef5 100644
--- a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
+++ b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
@@ -181,6 +181,7 @@ class M68kDAGToDAGISel : public SelectionDAGISel {
   }
 
   bool runOnMachineFunction(MachineFunction &MF) override;
+  bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const override;
 
 private:
   /// Keep a pointer to the M68kSubtarget around so that we can
@@ -311,6 +312,33 @@ class M68kDAGToDAGISel : public SelectionDAGISel {
 };
 } // namespace
 
+bool M68kDAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U,
+                                          SDNode *Root) const {
+  if (OptLevel == CodeGenOpt::None)
+    return false;
+
+  if (U == Root) {
+    switch (U->getOpcode()) {
+    default:
+      return true;
+    case M68kISD::SUB:
+    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;
+    }
+  }
+
+  return true;
+}
+
 bool M68kDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
   Subtarget = &MF.getSubtarget<M68kSubtarget>();
   return SelectionDAGISel::runOnMachineFunction(MF);

diff  --git a/llvm/test/CodeGen/M68k/Arith/imul-neg.ll b/llvm/test/CodeGen/M68k/Arith/imul-neg.ll
index 63b96309c1a68..7cb3e6b877357 100644
--- a/llvm/test/CodeGen/M68k/Arith/imul-neg.ll
+++ b/llvm/test/CodeGen/M68k/Arith/imul-neg.ll
@@ -1,14 +1,34 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=m68k-linux | FileCheck %s
-; FIXME: When using SelectionDAGISel, the following cases use
-; `sub` rather than the expected `neg`
+
+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
 ; CHECK-NEXT:  ; %bb.0:
-; CHECK-NEXT:    move.l #0, %d0
-; CHECK-NEXT:    sub.l (4,%sp), %d0
+; CHECK-NEXT:    move.l	(4,%sp), %d0
+; CHECK-NEXT:    neg.l	%d0
 ; CHECK-NEXT:    rts
     %mul = mul i32 %A, 4294967295
     ret i32 %mul
@@ -19,10 +39,10 @@ define i64 @mul18446744073709551615_64(i64 %A) {
 ; CHECK-LABEL: mul18446744073709551615_64:
 ; CHECK:         .cfi_startproc
 ; CHECK-NEXT:  ; %bb.0:
-; CHECK-NEXT:    move.l (4,%sp), %d0
-; CHECK-NEXT:    move.l #0, %d1
-; CHECK-NEXT:    sub.l (8,%sp), %d1
-; CHECK-NEXT:    negx.l %d0
+; CHECK-NEXT:    move.l	(4,%sp), %d0
+; CHECK-NEXT:    move.l	(8,%sp), %d1
+; CHECK-NEXT:    neg.l	%d1
+; CHECK-NEXT:    negx.l	%d0
 ; CHECK-NEXT:    rts
     %mul = mul i64 %A, 18446744073709551615
     ret i64 %mul


        


More information about the llvm-commits mailing list