diff --git a/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h b/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h --- a/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h +++ b/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h @@ -15,7 +15,7 @@ namespace llvm { class TargetTransformInfo; - +static unsigned GL_NUMPROMARGS = 3; //opt flag (if supplied) populates this Global Variable /// Argument promotion pass. /// /// This pass walks the functions in each SCC and for each one tries to @@ -25,7 +25,7 @@ unsigned MaxElements; public: - ArgumentPromotionPass(unsigned MaxElements = 3u) : MaxElements(MaxElements) {} + ArgumentPromotionPass(unsigned MaxElements = GL_NUMPROMARGS) : MaxElements(MaxElements) {} /// Check if callers and the callee \p F agree how promoted arguments would be /// passed. The ones that they do not agree on are eliminated from the sets but diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -90,6 +90,9 @@ #define DEBUG_TYPE "argpromotion" +//opt flag to capture user supplied value for GV: GL_NUMPROMARGS +cl::opt argmax("numargspromoted", cl::desc("Specify number of args to promote"), cl::value_desc("numargs"), cl::location(llvm::GL_NUMPROMARGS)); + STATISTIC(NumArgumentsPromoted, "Number of pointer arguments promoted"); STATISTIC(NumAggregatesPromoted, "Number of aggregate arguments promoted"); STATISTIC(NumByValArgsPromoted, "Number of byval arguments promoted"); @@ -1108,7 +1111,7 @@ "Promote 'by reference' arguments to scalars", false, false) Pass *llvm::createArgumentPromotionPass(unsigned MaxElements) { - return new ArgPromotion(MaxElements); + return new ArgPromotion(GL_NUMPROMARGS); } bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) { diff --git a/llvm/test/Transforms/ArgumentPromotion/magic-values/basictest.ll b/llvm/test/Transforms/ArgumentPromotion/magic-values/basictest.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/ArgumentPromotion/magic-values/basictest.ll @@ -0,0 +1,42 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; NOTE: three scenarios: 1) zero arguments promoted, 2) Baseline (current state = 3 args promoted), 3) infinite arguments promoted +; RUN: opt < %s -basicaa -argpromotion -numargspromoted=0 -mem2reg -S | FileCheck %s +; RUN: opt < %s -basicaa -argpromotion -mem2reg -S | FileCheck %s +; RUN: opt < %s -basicaa -argpromotion -numargspromoted=2147483647 -mem2reg -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" + +define internal i32 @test(i32* %X, i32* %Y) { +; CHECK-LABEL: define {{[^@]+}}@test +; CHECK-SAME: (i32 [[X_VAL:%.*]], i32 [[Y_VAL:%.*]]) +; CHECK-NEXT: [[C:%.*]] = add i32 [[X_VAL]], [[Y_VAL]] +; CHECK-NEXT: ret i32 [[C]] +; + %A = load i32, i32* %X + %B = load i32, i32* %Y + %C = add i32 %A, %B + ret i32 %C +} + +define internal i32 @caller(i32* %B) { +; CHECK-LABEL: define {{[^@]+}}@caller +; CHECK-SAME: (i32 [[B_VAL1:%.*]]) +; CHECK-NEXT: [[C:%.*]] = call i32 @test(i32 1, i32 [[B_VAL1]]) +; CHECK-NEXT: ret i32 [[C]] +; + %A = alloca i32 + store i32 1, i32* %A + %C = call i32 @test(i32* %A, i32* %B) + ret i32 %C +} + +define i32 @callercaller() { +; CHECK-LABEL: define {{[^@]+}}@callercaller() +; CHECK-NEXT: [[X:%.*]] = call i32 @caller(i32 2) +; CHECK-NEXT: ret i32 [[X]] +; + %B = alloca i32 + store i32 2, i32* %B + %X = call i32 @caller(i32* %B) + ret i32 %X +} + diff --git a/llvm/test/Transforms/ArgumentPromotion/magic-values/lit.local.cfg b/llvm/test/Transforms/ArgumentPromotion/magic-values/lit.local.cfg new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/ArgumentPromotion/magic-values/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'X86' in config.root.targets: + config.unsupported = True