[PATCH] D116145: [FuncSpec] Improve specializing direct constant

duanbo via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 22 00:10:09 PST 2021


duan.db created this revision.
duan.db added reviewers: ChuanqiXu, SjoerdMeijer.
Herald added subscribers: snehasish, ormris, hiraditya.
duan.db requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

I find that FuncSpec pass uses the option function-specialization-for-literal-constant to control whether specialize calls with direct constant.
But the control of this option may not be comprehensive enough. 
An example is given as the test case.


https://reviews.llvm.org/D116145

Files:
  llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
  llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-integers1.ll


Index: llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-integers1.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-integers1.ll
@@ -0,0 +1,48 @@
+; RUN: opt -function-specialization -function-specialization-for-literal-constant=true -force-function-specialization -S  < %s | FileCheck %s
+
+; Check that the literal constant parameter could be specialized.
+; CHECK: @f(
+; CHECK: @f.1(
+
+ at .str = private unnamed_addr constant [3 x i8] c"%d\00", align 1
+
+define dso_local i32 @main(i32 %argc, i8** %argv) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  %cmp = icmp slt i32 %i.0, 100
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %call = call i32 @f(i32 0, i32 %i.0)
+  %call1 = call i32 @f(i32 %i.0, i32 13)
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret i32 0
+}
+
+define internal i32 @f(i32 %a, i32 %x) {
+entry:
+  %cmp = icmp sgt i32 %a, 1
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  %mul = mul nsw i32 %a, %x
+  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32 %mul)
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  %sub = sub nsw i32 %a, %x
+  %call1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32 %sub)
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret i32 undef
+}
+
+declare dso_local noundef i32 @printf(i8* nocapture noundef readonly, ...)
+
Index: llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
===================================================================
--- llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
+++ llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
@@ -618,7 +618,8 @@
 
     // If the argument isn't overdefined, there's nothing to do. It should
     // already be constant.
-    if (!Solver.getLatticeValueFor(A).isOverdefined()) {
+    if (!EnableSpecializationForLiteralConstant &&
+        !Solver.getLatticeValueFor(A).isOverdefined()) {
       LLVM_DEBUG(dbgs() << "FnSpecialization: nothing to do, arg is already "
                         << "constant?\n");
       return false;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D116145.395801.patch
Type: text/x-patch
Size: 2656 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211222/1442a2c8/attachment.bin>


More information about the llvm-commits mailing list