forked from OSchip/llvm-project
[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
This commit is contained in:
parent
271a48e029
commit
78b16ccf2b
|
@ -181,6 +181,7 @@ public:
|
|||
}
|
||||
|
||||
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 @@ private:
|
|||
};
|
||||
} // 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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue