[llvm] [mlir][linalg][NFC] Make `LinalgOp` inherit from `DestinationStyleOpInterface` (#66995) (PR #68994)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 13 07:57:11 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Paul Walker (paulwalker-arm)

<details>
<summary>Changes</summary>

Dependent interfaces have been added a while ago and these TODOs can be
addressed now.

---
Full diff: https://github.com/llvm/llvm-project/pull/68994.diff


7 Files Affected:

- (modified) llvm/include/llvm/Analysis/TargetTransformInfo.h (+18) 
- (modified) llvm/include/llvm/Analysis/TargetTransformInfoImpl.h (+5) 
- (modified) llvm/lib/Analysis/TargetTransformInfo.cpp (+5) 
- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp (+19) 
- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h (+4) 
- (modified) llvm/lib/Transforms/Scalar/ConstantHoisting.cpp (+3-1) 
- (modified) llvm/test/Transforms/ConstantHoisting/AArch64/large-immediate.ll (+117-9) 


``````````diff
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 5234ef8788d9e96..aa2b7618734d45c 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -986,6 +986,18 @@ class TargetTransformInfo {
   /// more beneficial constant hoisting is).
   InstructionCost getIntImmCodeSizeCost(unsigned Opc, unsigned Idx,
                                         const APInt &Imm, Type *Ty) const;
+
+  /// Returns false if the target prefers to keep an instruction's constant
+  /// operands attached. It is not required for this function to perform
+  /// detailed constant analysis and in fact returning true does not imply
+  /// the instruction has any constant operands. This hook exists soley to
+  /// disable constant hoisting for reasons beyond the cost of generating a
+  /// constant. The motivating example is divides whereby hoisting constants
+  /// prevents the code generator's ability to transform them into combinations
+  /// of simpler operations.
+  bool isCandidateForConstantHoisting(const Instruction &Inst,
+                                      const Function &Fn) const;
+
   /// @}
 
   /// \name Vector Target Information
@@ -1847,6 +1859,8 @@ class TargetTransformInfo::Concept {
   virtual InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
                                               const APInt &Imm, Type *Ty,
                                               TargetCostKind CostKind) = 0;
+  virtual bool isCandidateForConstantHoisting(const Instruction &Inst,
+                                              const Function &Fn) const = 0;
   virtual unsigned getNumberOfRegisters(unsigned ClassID) const = 0;
   virtual unsigned getRegisterClassForType(bool Vector,
                                            Type *Ty = nullptr) const = 0;
@@ -2399,6 +2413,10 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
                                       TargetCostKind CostKind) override {
     return Impl.getIntImmCostIntrin(IID, Idx, Imm, Ty, CostKind);
   }
+  bool isCandidateForConstantHoisting(const Instruction &Inst,
+                                      const Function &Fn) const override {
+    return Impl.isCandidateForConstantHoisting(Inst, Fn);
+  }
   unsigned getNumberOfRegisters(unsigned ClassID) const override {
     return Impl.getNumberOfRegisters(ClassID);
   }
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index c1ff314ae51c98b..0dfe9e8d0c96ac2 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -425,6 +425,11 @@ class TargetTransformInfoImplBase {
     return TTI::TCC_Free;
   }
 
+  bool isCandidateForConstantHoisting(const Instruction &Inst,
+                                      const Function &Fn) const {
+    return true;
+  }
+
   unsigned getNumberOfRegisters(unsigned ClassID) const { return 8; }
 
   unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const {
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index aad14f21d114619..1341589f5fbf809 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -678,6 +678,11 @@ TargetTransformInfo::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
   return Cost;
 }
 
+bool TargetTransformInfo::isCandidateForConstantHoisting(
+    const Instruction &Inst, const Function &Fn) const {
+  return TTIImpl->isCandidateForConstantHoisting(Inst, Fn);
+}
+
 unsigned TargetTransformInfo::getNumberOfRegisters(unsigned ClassID) const {
   return TTIImpl->getNumberOfRegisters(ClassID);
 }
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index d8a0e68d7123759..83eef059b107988 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -382,6 +382,25 @@ AArch64TTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
   return AArch64TTIImpl::getIntImmCost(Imm, Ty, CostKind);
 }
 
+bool AArch64TTIImpl::isCandidateForConstantHoisting(const Instruction &Inst,
+                                                    const Function &Fn) const {
+  switch (Inst.getOpcode()) {
+  default:
+    break;
+  case Instruction::SDiv:
+  case Instruction::SRem:
+  case Instruction::UDiv:
+  case Instruction::URem: {
+    if (!isa<ConstantInt>(Inst.getOperand(1)))
+      return true;
+    EVT VT = TLI->getValueType(DL, Inst.getType());
+    return TLI->isIntDivCheap(VT, Fn.getAttributes());
+  }
+  };
+
+  return true;
+}
+
 TargetTransformInfo::PopcntSupportKind
 AArch64TTIImpl::getPopcntSupport(unsigned TyWidth) {
   assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
index a6baade412c77d2..a2ac4b6aa46f44c 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
@@ -91,6 +91,10 @@ class AArch64TTIImpl : public BasicTTIImplBase<AArch64TTIImpl> {
   InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
                                       const APInt &Imm, Type *Ty,
                                       TTI::TargetCostKind CostKind);
+
+  bool isCandidateForConstantHoisting(const Instruction &Inst,
+                                      const Function &Fn) const;
+
   TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth);
 
   /// @}
diff --git a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
index 3e5d979f11cc50a..233a1a7bf82ce15 100644
--- a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
@@ -523,7 +523,9 @@ void ConstantHoistingPass::collectConstantCandidates(Function &Fn) {
     if (!DT->isReachableFromEntry(&BB))
       continue;
     for (Instruction &Inst : BB)
-      collectConstantCandidates(ConstCandMap, &Inst);
+      // Skip instructions the target prefers constants remain attached.
+      if (TTI->isCandidateForConstantHoisting(Inst, Fn))
+        collectConstantCandidates(ConstCandMap, &Inst);
   }
 }
 
diff --git a/llvm/test/Transforms/ConstantHoisting/AArch64/large-immediate.ll b/llvm/test/Transforms/ConstantHoisting/AArch64/large-immediate.ll
index 015f52157b9e7c7..fe8c699e72d9980 100644
--- a/llvm/test/Transforms/ConstantHoisting/AArch64/large-immediate.ll
+++ b/llvm/test/Transforms/ConstantHoisting/AArch64/large-immediate.ll
@@ -1,27 +1,135 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
 ; RUN: opt -mtriple=arm64-darwin-unknown -S -passes=consthoist < %s | FileCheck %s
 
-define i128 @test1(i128 %a) nounwind {
-; CHECK-LABEL: test1
-; CHECK: %const = bitcast i128 12297829382473034410122878 to i128
+define i128 @test1(i128 %a) {
+; CHECK-LABEL: define i128 @test1(
+; CHECK-SAME: i128 [[A:%.*]]) {
+; CHECK-NEXT:    [[CONST:%.*]] = bitcast i128 12297829382473034410122878 to i128
+; CHECK-NEXT:    [[TMP1:%.*]] = add i128 [[A]], [[CONST]]
+; CHECK-NEXT:    [[TMP2:%.*]] = add i128 [[TMP1]], [[CONST]]
+; CHECK-NEXT:    ret i128 [[TMP2]]
+;
   %1 = add i128 %a, 12297829382473034410122878
   %2 = add i128 %1, 12297829382473034410122878
   ret i128 %2
 }
 
 ; Check that we don't hoist large, but cheap constants
-define i512 @test2(i512 %a) nounwind {
-; CHECK-LABEL: test2
-; CHECK-NOT: %const = bitcast i512 7 to i512
+define i512 @test2(i512 %a) {
+; CHECK-LABEL: define i512 @test2(
+; CHECK-SAME: i512 [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = and i512 [[A]], 7
+; CHECK-NEXT:    [[TMP2:%.*]] = or i512 [[TMP1]], 7
+; CHECK-NEXT:    ret i512 [[TMP2]]
+;
   %1 = and i512 %a, 7
   %2 = or i512 %1, 7
   ret i512 %2
 }
 
 ; Check that we don't hoist the shift value of a shift instruction.
-define i512 @test3(i512 %a) nounwind {
-; CHECK-LABEL: test3
-; CHECK-NOT: %const = bitcast i512 504 to i512
+define i512 @test3(i512 %a) {
+; CHECK-LABEL: define i512 @test3(
+; CHECK-SAME: i512 [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i512 [[A]], 504
+; CHECK-NEXT:    [[TMP2:%.*]] = ashr i512 [[TMP1]], 504
+; CHECK-NEXT:    ret i512 [[TMP2]]
+;
   %1 = shl i512 %a, 504
   %2 = ashr i512 %1, 504
   ret i512 %2
 }
+
+; Ensure the code generator has the information necessary to simply sdiv.
+define i64 @sdiv(i64 %a) {
+; CHECK-LABEL: define i64 @sdiv(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = sdiv i64 [[A]], 4294967087
+; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
+; CHECK-NEXT:    ret i64 [[TMP2]]
+;
+  %1 = sdiv i64 %a, 4294967087
+  %2 = add i64 %1, 4294967087
+  ret i64 %2
+}
+
+; Ensure the code generator has the information necessary to simply srem.
+define i64 @srem(i64 %a) {
+; CHECK-LABEL: define i64 @srem(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = srem i64 [[A]], 4294967087
+; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
+; CHECK-NEXT:    ret i64 [[TMP2]]
+;
+  %1 = srem i64 %a, 4294967087
+  %2 = add i64 %1, 4294967087
+  ret i64 %2
+}
+
+; Ensure the code generator has the information necessary to simply udiv.
+define i64 @udiv(i64 %a) {
+; CHECK-LABEL: define i64 @udiv(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = udiv i64 [[A]], 4294967087
+; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
+; CHECK-NEXT:    ret i64 [[TMP2]]
+;
+  %1 = udiv i64 %a, 4294967087
+  %2 = add i64 %1, 4294967087
+  ret i64 %2
+}
+
+; Ensure the code generator has the information necessary to simply urem.
+define i64 @urem(i64 %a) {
+; CHECK-LABEL: define i64 @urem(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = urem i64 [[A]], 4294967087
+; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
+; CHECK-NEXT:    ret i64 [[TMP2]]
+;
+  %1 = urem i64 %a, 4294967087
+  %2 = add i64 %1, 4294967087
+  ret i64 %2
+}
+
+; Code generator will not decompose divide like operations when the divisor is
+; no a constant.
+define i64 @sdiv_non_const_divisor(i64 %a) {
+; CHECK-LABEL: define i64 @sdiv_non_const_divisor(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT:    [[CONST:%.*]] = bitcast i64 4294967087 to i64
+; CHECK-NEXT:    [[TMP1:%.*]] = sdiv i64 [[CONST]], [[A]]
+; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], [[CONST]]
+; CHECK-NEXT:    ret i64 [[TMP2]]
+;
+  %1 = sdiv i64 4294967087, %a
+  %2 = add i64 %1, 4294967087
+  ret i64 %2
+}
+
+; Code generator emits divide instructions when optimising for size.
+define i64 @sdiv_minsize(i64 %a) minsize {
+; CHECK-LABEL: define i64 @sdiv_minsize(
+; CHECK-SAME: i64 [[A:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[CONST:%.*]] = bitcast i64 4294967087 to i64
+; CHECK-NEXT:    [[TMP1:%.*]] = sdiv i64 [[A]], [[CONST]]
+; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], [[CONST]]
+; CHECK-NEXT:    ret i64 [[TMP2]]
+;
+  %1 = sdiv i64 %a, 4294967087
+  %2 = add i64 %1, 4294967087
+  ret i64 %2
+}
+
+; Code generator will not decompose vector divide like operations.
+define <2 x i64> @sdiv_v2i64(<2 x i64> %a) {
+; CHECK-LABEL: define <2 x i64> @sdiv_v2i64(
+; CHECK-SAME: <2 x i64> [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = sdiv <2 x i64> [[A]], <i64 4294967087, i64 4294967087>
+; CHECK-NEXT:    [[TMP2:%.*]] = add <2 x i64> [[TMP1]], <i64 4294967087, i64 4294967087>
+; CHECK-NEXT:    ret <2 x i64> [[TMP2]]
+;
+  %1 = sdiv <2 x i64> %a, <i64 4294967087, i64 4294967087>
+  %2 = add <2 x i64> %1, <i64 4294967087, i64 4294967087>
+  ret <2 x i64> %2
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/68994


More information about the llvm-commits mailing list