Revert "[FuncSpec] Fix specialisation based on literals"
authorMomchil Velikov <momchil.velikov@arm.com>
Wed, 26 Oct 2022 12:49:18 +0000 (13:49 +0100)
committerMomchil Velikov <momchil.velikov@arm.com>
Wed, 26 Oct 2022 12:54:12 +0000 (13:54 +0100)
This reverts commit a8b0f580170089fcd555ade5565ceff0ec60f609 because
of "reverse-iteration" buildbot failure.

llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
llvm/test/Transforms/FunctionSpecialization/literal-const.ll [deleted file]

index 4bf1688..c918585 100644 (file)
@@ -666,35 +666,17 @@ private:
   /// argument.
   bool isArgumentInteresting(Argument *A,
                              SmallVectorImpl<CallArgBinding> &Constants) {
-
-    // No point in specialization if the argument is unused.
-    if (A->user_empty())
-      return false;
-
     // For now, don't attempt to specialize functions based on the values of
     // composite types.
-    Type *ArgTy = A->getType()                              ;
-    if (!ArgTy->isSingleValueType())
-      return false;
-
-    // Specialization of integer and floating point types needs to be explicitly enabled.
-    if (!EnableSpecializationForLiteralConstant &&
-        (ArgTy->isIntegerTy() || ArgTy->isFloatingPointTy()))
+    if (!A->getType()->isSingleValueType() || A->user_empty())
       return false;
 
-    // SCCP solver does not record an argument that will be constructed on
-    // stack.
-    if (A->hasByValAttr() && !A->getParent()->onlyReadsMemory())
-      return false;
-
-    // Check the lattice value and decide if we should attemt to specialize,
-    // based on this argument. No point in specialization, if the lattice value
-    // is already a constant.
-    const ValueLatticeElement &LV = Solver.getLatticeValueFor(A);
-    if (LV.isUnknownOrUndef() || LV.isConstant() ||
-        (LV.isConstantRange() && LV.getConstantRange().isSingleElement())) {
+    // If the argument isn't overdefined, there's nothing to do. It should
+    // already be constant.
+    if (!Solver.getLatticeValueFor(A).isOverdefined()) {
       LLVM_DEBUG(dbgs() << "FnSpecialization: Nothing to do, argument "
-                        << A->getNameOrAsOperand() << " is already constant\n");
+                        << A->getNameOrAsOperand()
+                        << " is already constant?\n");
       return false;
     }
 
@@ -727,6 +709,11 @@ private:
                             SmallVectorImpl<CallArgBinding> &Constants) {
     Function *F = A->getParent();
 
+    // SCCP solver does not record an argument that will be constructed on
+    // stack.
+    if (A->hasByValAttr() && !F->onlyReadsMemory())
+      return;
+
     // Iterate over all the call sites of the argument's parent function.
     for (User *U : F->users()) {
       if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
@@ -757,23 +744,9 @@ private:
           continue;
       }
 
-      // Select for possible specialisation arguments which are constants or
-      // are deduced to be constants or constant ranges with a single element.
-      Constant *C = dyn_cast<Constant>(V);
-      if (!C) {
-        const ValueLatticeElement &LV = Solver.getLatticeValueFor(V);
-        if (LV.isConstant())
-          C = LV.getConstant();
-        else if (LV.isConstantRange() &&
-                 LV.getConstantRange().isSingleElement()) {
-          assert(V->getType()->isIntegerTy() && "Non-integral constant range");
-          C = Constant::getIntegerValue(
-              V->getType(), *LV.getConstantRange().getSingleElement());
-        } else
-          continue;
-      }
-
-      Constants.push_back({&CS, C});
+      if (isa<Constant>(V) && (Solver.getLatticeValueFor(V).isConstant() ||
+                               EnableSpecializationForLiteralConstant))
+        Constants.push_back({&CS, cast<Constant>(V)});
     }
   }
 
diff --git a/llvm/test/Transforms/FunctionSpecialization/literal-const.ll b/llvm/test/Transforms/FunctionSpecialization/literal-const.ll
deleted file mode 100644 (file)
index 9bd9440..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-; RUN: opt -S --passes=function-specialization \
-; RUN:        -force-function-specialization < %s | FileCheck %s -check-prefix CHECK-NOLIT
-; RUN: opt -S --passes=function-specialization \
-; RUN:        -function-specialization-for-literal-constant \
-; RUN:        -force-function-specialization < %s | FileCheck %s -check-prefix CHECK-LIT
-
-define dso_local i32 @f0(i32 noundef %x) {
-entry:
-  %call = tail call fastcc i32 @neg(i32 noundef %x, i1 noundef zeroext false)
-  ret i32 %call
-}
-
-define internal fastcc i32 @neg(i32 noundef %x, i1 noundef zeroext %b) {
-entry:
-  %sub = sub nsw i32 0, %x
-  %cond = select i1 %b, i32 %sub, i32 %x
-  ret i32 %cond
-}
-
-define dso_local i32 @f1(i32 noundef %x) {
-entry:
-  %call = tail call fastcc i32 @neg(i32 noundef %x, i1 noundef zeroext true)
-  ret i32 %call
-}
-
-define dso_local i32 @g0(i32 noundef %x) {
-entry:
-  %call = tail call fastcc i32 @add(i32 noundef %x, i32 noundef 1)
-  ret i32 %call
-}
-
-define internal fastcc i32 @add(i32 noundef %x, i32 noundef %y) {
-entry:
-  %add = add nsw i32 %y, %x
-  ret i32 %add
-}
-
-define dso_local i32 @g1(i32 noundef %x) {
-entry:
-  %call = tail call fastcc i32 @add(i32 noundef %x, i32 noundef 2)
-  ret i32 %call
-}
-
-define dso_local float @h0(float noundef %x) {
-entry:
-  %call = tail call fastcc float @addf(float noundef %x, float noundef 1.000000e+00)
-  ret float %call
-}
-
-define internal fastcc float @addf(float noundef %x, float noundef %y) {
-entry:
-  %add = fadd float %x, %y
-  ret float %add
-}
-
-define dso_local float @h1(float noundef %x) {
-entry:
-  %call = tail call fastcc float @addf(float noundef %x, float noundef 2.000000e+00)
-  ret float %call
-}
-
-; Check no functions were specialised.
-; CHECK-NOLIT-NOT: @neg.
-; CHECK-NOLIT-NOT: @add.
-; CHECK-NOLIT-NOT: @addf.
-
-; Check all of `neg`, `add`, and `addf` were specialised.
-; CHECK-LIT-DAG: @neg.1
-; CHECK-LIT-DAG: @neg.2
-; CHECK-LIT-DAG: @add.3
-; CHECK-LIT-DAG: @add.4
-; CHECK-LIT-DAG: @addf.5
-; CHECK-LIT-DAG: @addf.6