forked from OSchip/llvm-project
[Mips] Implement hasDivRemOp()
SDIVREM and UDIVREM can be customized lowered in MipsSE. Fix https://github.com/llvm/llvm-project/issues/54991. Reviewed By: sdardis Differential Revision: https://reviews.llvm.org/D124980
This commit is contained in:
parent
49b0c60542
commit
0a0d6489ef
|
@ -61,6 +61,7 @@ add_llvm_target(MipsCodeGen
|
|||
MipsSubtarget.cpp
|
||||
MipsTargetMachine.cpp
|
||||
MipsTargetObjectFile.cpp
|
||||
MipsTargetTransformInfo.cpp
|
||||
MicroMipsSizeReduction.cpp
|
||||
MipsMulMulBugPass.cpp
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "MipsSEISelDAGToDAG.h"
|
||||
#include "MipsSubtarget.h"
|
||||
#include "MipsTargetObjectFile.h"
|
||||
#include "MipsTargetTransformInfo.h"
|
||||
#include "TargetInfo/MipsTargetInfo.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
@ -287,7 +288,7 @@ MipsTargetMachine::getTargetTransformInfo(const Function &F) const {
|
|||
}
|
||||
|
||||
LLVM_DEBUG(errs() << "Target Transform Info Pass Added\n");
|
||||
return TargetTransformInfo(BasicTTIImpl(this, F));
|
||||
return TargetTransformInfo(MipsTTIImpl(this, F));
|
||||
}
|
||||
|
||||
// Implemented by targets that want to run passes immediately before
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
//===-- MipsTargetTransformInfo.cpp - Mips specific TTI ----------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MipsTargetTransformInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
bool MipsTTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) {
|
||||
EVT VT = TLI->getValueType(DL, DataType);
|
||||
return TLI->isOperationLegalOrCustom(IsSigned ? ISD::SDIVREM : ISD::UDIVREM,
|
||||
VT);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
//===-- MipsTargetTransformInfo.h - Mips specific TTI -----------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_MIPS_MIPSTARGETTRANSFORMINFO_H
|
||||
#define LLVM_LIB_TARGET_MIPS_MIPSTARGETTRANSFORMINFO_H
|
||||
|
||||
#include "MipsTargetMachine.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/CodeGen/BasicTTIImpl.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MipsTTIImpl : public BasicTTIImplBase<MipsTTIImpl> {
|
||||
using BaseT = BasicTTIImplBase<MipsTTIImpl>;
|
||||
using TTI = TargetTransformInfo;
|
||||
|
||||
friend BaseT;
|
||||
|
||||
const MipsSubtarget *ST;
|
||||
const MipsTargetLowering *TLI;
|
||||
|
||||
const MipsSubtarget *getST() const { return ST; }
|
||||
const MipsTargetLowering *getTLI() const { return TLI; }
|
||||
|
||||
public:
|
||||
explicit MipsTTIImpl(const MipsTargetMachine *TM, const Function &F)
|
||||
: BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
|
||||
TLI(ST->getTargetLowering()) {}
|
||||
|
||||
bool hasDivRemOp(Type *DataType, bool IsSigned);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
|
@ -7,8 +7,8 @@ define void @decompose_illegal_srem_same_block(i32 %a, i32 %b) {
|
|||
; CHECK-LABEL: @decompose_illegal_srem_same_block(
|
||||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[T0:%.*]] = mul i32 [[DIV]], [[B]]
|
||||
; CHECK-NEXT: [[REM:%.*]] = sub i32 [[A]], [[T0]]
|
||||
; CHECK-NEXT: call void @foo(i32 [[REM]], i32 [[DIV]])
|
||||
; CHECK-NEXT: [[REM_RECOMPOSED:%.*]] = srem i32 [[A]], [[B]]
|
||||
; CHECK-NEXT: call void @foo(i32 [[REM_RECOMPOSED]], i32 [[DIV]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%div = sdiv i32 %a, %b
|
||||
|
@ -22,8 +22,8 @@ define void @decompose_illegal_urem_same_block(i32 %a, i32 %b) {
|
|||
; CHECK-LABEL: @decompose_illegal_urem_same_block(
|
||||
; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[T0:%.*]] = mul i32 [[DIV]], [[B]]
|
||||
; CHECK-NEXT: [[REM:%.*]] = sub i32 [[A]], [[T0]]
|
||||
; CHECK-NEXT: call void @foo(i32 [[REM]], i32 [[DIV]])
|
||||
; CHECK-NEXT: [[REM_RECOMPOSED:%.*]] = urem i32 [[A]], [[B]]
|
||||
; CHECK-NEXT: call void @foo(i32 [[REM_RECOMPOSED]], i32 [[DIV]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%div = udiv i32 %a, %b
|
||||
|
@ -100,18 +100,13 @@ end:
|
|||
define i32 @srem_of_srem_unexpanded(i32 %X, i32 %Y, i32 %Z) {
|
||||
; CHECK-LABEL: @srem_of_srem_unexpanded(
|
||||
; CHECK-NEXT: [[T0:%.*]] = mul nsw i32 [[Z:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[X_FROZEN:%.*]] = freeze i32 [[X:%.*]]
|
||||
; CHECK-NEXT: [[T0_FROZEN:%.*]] = freeze i32 [[T0]]
|
||||
; CHECK-NEXT: [[T1:%.*]] = sdiv i32 [[X_FROZEN]], [[T0_FROZEN]]
|
||||
; CHECK-NEXT: [[T1:%.*]] = sdiv i32 [[X:%.*]], [[T0]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = mul nsw i32 [[T0]], [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[T1]], [[T0_FROZEN]]
|
||||
; CHECK-NEXT: [[T3_DECOMPOSED:%.*]] = sub i32 [[X_FROZEN]], [[TMP1]]
|
||||
; CHECK-NEXT: [[Y_FROZEN:%.*]] = freeze i32 [[Y]]
|
||||
; CHECK-NEXT: [[T4:%.*]] = sdiv i32 [[T3_DECOMPOSED]], [[Y_FROZEN]]
|
||||
; CHECK-NEXT: [[T3:%.*]] = srem i32 [[X]], [[T0]]
|
||||
; CHECK-NEXT: [[T4:%.*]] = sdiv i32 [[T3]], [[Y]]
|
||||
; CHECK-NEXT: [[T5:%.*]] = mul nsw i32 [[T4]], [[Y]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[T4]], [[Y_FROZEN]]
|
||||
; CHECK-NEXT: [[T6_DECOMPOSED:%.*]] = sub i32 [[T3_DECOMPOSED]], [[TMP2]]
|
||||
; CHECK-NEXT: ret i32 [[T6_DECOMPOSED]]
|
||||
; CHECK-NEXT: [[T6:%.*]] = srem i32 [[T3]], [[Y]]
|
||||
; CHECK-NEXT: ret i32 [[T6]]
|
||||
;
|
||||
%t0 = mul nsw i32 %Z, %Y
|
||||
%t1 = sdiv i32 %X, %t0
|
||||
|
@ -127,11 +122,11 @@ define i32 @srem_of_srem_expanded(i32 %X, i32 %Y, i32 %Z) {
|
|||
; CHECK-NEXT: [[T0:%.*]] = mul nsw i32 [[Z:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[T1:%.*]] = sdiv i32 [[X:%.*]], [[T0]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = mul nsw i32 [[T0]], [[T1]]
|
||||
; CHECK-NEXT: [[T3:%.*]] = sub nsw i32 [[X]], [[T2]]
|
||||
; CHECK-NEXT: [[T4:%.*]] = sdiv i32 [[T3]], [[Y]]
|
||||
; CHECK-NEXT: [[T3_RECOMPOSED:%.*]] = srem i32 [[X]], [[T0]]
|
||||
; CHECK-NEXT: [[T4:%.*]] = sdiv i32 [[T3_RECOMPOSED]], [[Y]]
|
||||
; CHECK-NEXT: [[T5:%.*]] = mul nsw i32 [[T4]], [[Y]]
|
||||
; CHECK-NEXT: [[T6:%.*]] = sub nsw i32 [[T3]], [[T5]]
|
||||
; CHECK-NEXT: ret i32 [[T6]]
|
||||
; CHECK-NEXT: [[T6_RECOMPOSED:%.*]] = srem i32 [[T3_RECOMPOSED]], [[Y]]
|
||||
; CHECK-NEXT: ret i32 [[T6_RECOMPOSED]]
|
||||
;
|
||||
%t0 = mul nsw i32 %Z, %Y
|
||||
%t1 = sdiv i32 %X, %t0
|
||||
|
|
|
@ -5,12 +5,9 @@ declare void @foo(i32, i32)
|
|||
|
||||
define void @decompose_illegal_srem_same_block(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @decompose_illegal_srem_same_block(
|
||||
; CHECK-NEXT: [[A_FROZEN:%.*]] = freeze i32 [[A:%.*]]
|
||||
; CHECK-NEXT: [[B_FROZEN:%.*]] = freeze i32 [[B:%.*]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A_FROZEN]], [[B_FROZEN]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], [[B_FROZEN]]
|
||||
; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub i32 [[A_FROZEN]], [[TMP1]]
|
||||
; CHECK-NEXT: call void @foo(i32 [[REM_DECOMPOSED]], i32 [[DIV]])
|
||||
; CHECK-NEXT: [[REM:%.*]] = srem i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A]], [[B]]
|
||||
; CHECK-NEXT: call void @foo(i32 [[REM]], i32 [[DIV]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%rem = srem i32 %a, %b
|
||||
|
@ -21,12 +18,9 @@ define void @decompose_illegal_srem_same_block(i32 %a, i32 %b) {
|
|||
|
||||
define void @decompose_illegal_urem_same_block(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @decompose_illegal_urem_same_block(
|
||||
; CHECK-NEXT: [[A_FROZEN:%.*]] = freeze i32 [[A:%.*]]
|
||||
; CHECK-NEXT: [[B_FROZEN:%.*]] = freeze i32 [[B:%.*]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[A_FROZEN]], [[B_FROZEN]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], [[B_FROZEN]]
|
||||
; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub i32 [[A_FROZEN]], [[TMP1]]
|
||||
; CHECK-NEXT: call void @foo(i32 [[REM_DECOMPOSED]], i32 [[DIV]])
|
||||
; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[REM:%.*]] = urem i32 [[A]], [[B]]
|
||||
; CHECK-NEXT: call void @foo(i32 [[REM]], i32 [[DIV]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%div = udiv i32 %a, %b
|
||||
|
@ -41,12 +35,9 @@ define void @decompose_illegal_urem_same_block(i32 %a, i32 %b) {
|
|||
define i32 @hoist_sdiv(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @hoist_sdiv(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[A_FROZEN:%.*]] = freeze i32 [[A:%.*]]
|
||||
; CHECK-NEXT: [[B_FROZEN:%.*]] = freeze i32 [[B:%.*]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A_FROZEN]], [[B_FROZEN]]
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[DIV]], [[B_FROZEN]]
|
||||
; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub i32 [[A_FROZEN]], [[TMP0]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM_DECOMPOSED]], 42
|
||||
; CHECK-NEXT: [[REM:%.*]] = srem i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A]], [[B]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 42
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
|
||||
; CHECK: if:
|
||||
; CHECK-NEXT: br label [[END]]
|
||||
|
@ -169,18 +160,13 @@ end:
|
|||
define i32 @srem_of_srem_unexpanded(i32 %X, i32 %Y, i32 %Z) {
|
||||
; CHECK-LABEL: @srem_of_srem_unexpanded(
|
||||
; CHECK-NEXT: [[T0:%.*]] = mul nsw i32 [[Z:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[X_FROZEN:%.*]] = freeze i32 [[X:%.*]]
|
||||
; CHECK-NEXT: [[T0_FROZEN:%.*]] = freeze i32 [[T0]]
|
||||
; CHECK-NEXT: [[T1:%.*]] = sdiv i32 [[X_FROZEN]], [[T0_FROZEN]]
|
||||
; CHECK-NEXT: [[T1:%.*]] = sdiv i32 [[X:%.*]], [[T0]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = mul nsw i32 [[T0]], [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[T1]], [[T0_FROZEN]]
|
||||
; CHECK-NEXT: [[T3_DECOMPOSED:%.*]] = sub i32 [[X_FROZEN]], [[TMP1]]
|
||||
; CHECK-NEXT: [[Y_FROZEN:%.*]] = freeze i32 [[Y]]
|
||||
; CHECK-NEXT: [[T4:%.*]] = sdiv i32 [[T3_DECOMPOSED]], [[Y_FROZEN]]
|
||||
; CHECK-NEXT: [[T3:%.*]] = srem i32 [[X]], [[T0]]
|
||||
; CHECK-NEXT: [[T4:%.*]] = sdiv i32 [[T3]], [[Y]]
|
||||
; CHECK-NEXT: [[T5:%.*]] = mul nsw i32 [[T4]], [[Y]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[T4]], [[Y_FROZEN]]
|
||||
; CHECK-NEXT: [[T6_DECOMPOSED:%.*]] = sub i32 [[T3_DECOMPOSED]], [[TMP2]]
|
||||
; CHECK-NEXT: ret i32 [[T6_DECOMPOSED]]
|
||||
; CHECK-NEXT: [[T6:%.*]] = srem i32 [[T3]], [[Y]]
|
||||
; CHECK-NEXT: ret i32 [[T6]]
|
||||
;
|
||||
%t0 = mul nsw i32 %Z, %Y
|
||||
%t1 = sdiv i32 %X, %t0
|
||||
|
@ -196,11 +182,11 @@ define i32 @srem_of_srem_expanded(i32 %X, i32 %Y, i32 %Z) {
|
|||
; CHECK-NEXT: [[T0:%.*]] = mul nsw i32 [[Z:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[T1:%.*]] = sdiv i32 [[X:%.*]], [[T0]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = mul nsw i32 [[T0]], [[T1]]
|
||||
; CHECK-NEXT: [[T3:%.*]] = sub nsw i32 [[X]], [[T2]]
|
||||
; CHECK-NEXT: [[T4:%.*]] = sdiv i32 [[T3]], [[Y]]
|
||||
; CHECK-NEXT: [[T3_RECOMPOSED:%.*]] = srem i32 [[X]], [[T0]]
|
||||
; CHECK-NEXT: [[T4:%.*]] = sdiv i32 [[T3_RECOMPOSED]], [[Y]]
|
||||
; CHECK-NEXT: [[T5:%.*]] = mul nsw i32 [[T4]], [[Y]]
|
||||
; CHECK-NEXT: [[T6:%.*]] = sub nsw i32 [[T3]], [[T5]]
|
||||
; CHECK-NEXT: ret i32 [[T6]]
|
||||
; CHECK-NEXT: [[T6_RECOMPOSED:%.*]] = srem i32 [[T3_RECOMPOSED]], [[Y]]
|
||||
; CHECK-NEXT: ret i32 [[T6_RECOMPOSED]]
|
||||
;
|
||||
%t0 = mul nsw i32 %Z, %Y
|
||||
%t1 = sdiv i32 %X, %t0
|
||||
|
|
Loading…
Reference in New Issue