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 @@ -14,8 +14,10 @@ #include "llvm/IR/PassManager.h" namespace llvm { +//opt flag (if supplied) populates this Global Variable in the llvm namespace. Default value is set to 3, as was exisiting before. +//This global value can be changed via user input to set the maximum number of members that can be promoted with an aggregate. +static unsigned GL_NUMPROMARGS = 3; 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 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,12 +90,8 @@ #define DEBUG_TYPE "argpromotion" -<<<<<<< HEAD //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)); -======= -cl::opt argmax("maxar", cl::Required, cl::desc("Specify number of args to promote"), cl::value_desc("maxargs"), cl::location(llvm::GL_MAXARGS)); ->>>>>>> df0f0e791671d16f15d67c1f265b75f5a35a7624 STATISTIC(NumArgumentsPromoted, "Number of pointer arguments promoted"); STATISTIC(NumAggregatesPromoted, "Number of aggregate arguments promoted"); @@ -1076,7 +1072,7 @@ // Pass identification, replacement for typeid static char ID; - explicit ArgPromotion(unsigned MaxElements = 3) + explicit ArgPromotion(unsigned MaxElements = GL_NUMPROMARGS) : CallGraphSCCPass(ID), MaxElements(MaxElements) { initializeArgPromotionPass(*PassRegistry::getPassRegistry()); } @@ -1115,11 +1111,7 @@ "Promote 'by reference' arguments to scalars", false, false) Pass *llvm::createArgumentPromotionPass(unsigned MaxElements) { -<<<<<<< HEAD return new ArgPromotion(GL_NUMPROMARGS); -======= - return new ArgPromotion(GL_MAXARGS); ->>>>>>> df0f0e791671d16f15d67c1f265b75f5a35a7624 } bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) { diff --git a/llvm/test/Transforms/ArgumentPromotion/fourmember-struct-promote-DEFAULT.ll b/llvm/test/Transforms/ArgumentPromotion/fourmember-struct-promote-DEFAULT.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/ArgumentPromotion/fourmember-struct-promote-DEFAULT.ll @@ -0,0 +1,91 @@ +; RUN: opt < %s -basic-aa -mem2reg -argpromotion -mem2reg -S | FileCheck %s + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +%struct.fourmem = type { i32, i32, i32, i32 } + +; Function Attrs: noinline norecurse ssp uwtable +define i32 @main() #0 { +; CHECK-LABEL: define {{[^@]+}}@main() +; CHECK-NEXT: entry: +; CHECK-NEXT: [[F:%.*]] = alloca {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 0 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 1 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 2 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 3 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: %{{.*}} = call i32 @{{.*}}fourmem(i32 [[F]].idx{{.*}}.val, i32 [[F]].idx{{.*}}.val, i32 [[F]].idx{{.*}}.val, i32 [[F]].idx{{.*}}.val) +; CHECK-NEXT: ret i32 0 +; +entry: + %retval = alloca i32, align 4 + %four = alloca %struct.fourmem, align 4 + %T = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + %a = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 0 + store i32 1, i32* %a, align 4 + %b = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 1 + store i32 2, i32* %b, align 4 + %c = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 2 + store i32 3, i32* %c, align 4 + %d = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 3 + store i32 4, i32* %d, align 4 + %call = call i32 @_ZL6calleeP7fourmem(%struct.fourmem* %four) + store i32 %call, i32* %T, align 4 + ret i32 0 +} + +; Function Attrs: noinline nounwind ssp uwtable +define internal i32 @_ZL6calleeP7fourmem(%struct.fourmem* %t) #1 { +; CHECK-LABEL: define {{[^@]+}}@{{.*}}fourmem +; CHECK-SAME: (i32 %t.0.{{.*}}.val, i32 %t.0.{{.*}}.val, i32 %t.0.{{.*}}.val, i32 %t.0.{{.*}}.val) +; CHECK-NEXT: entry: +; CHECK-NEXT: %add{{.*}} = add nsw i32 {{.*}}, {{.*}} +; CHECK-NEXT: %add{{.*}} = add nsw i32 {{.*}}, {{.*}} +; CHECK-NEXT: %add{{.*}} = add nsw i32 {{.*}}, {{.*}} +; CHECK-NEXT: ret i32 %{{.*}} +; +entry: + %t.addr = alloca %struct.fourmem*, align 8 + %S = alloca i32, align 4 + store %struct.fourmem* %t, %struct.fourmem** %t.addr, align 8 + %0 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %a = getelementptr inbounds %struct.fourmem, %struct.fourmem* %0, i32 0, i32 0 + %1 = load i32, i32* %a, align 4 + %2 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %b = getelementptr inbounds %struct.fourmem, %struct.fourmem* %2, i32 0, i32 1 + %3 = load i32, i32* %b, align 4 + %add = add nsw i32 %1, %3 + %4 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %c = getelementptr inbounds %struct.fourmem, %struct.fourmem* %4, i32 0, i32 2 + %5 = load i32, i32* %c, align 4 + %add1 = add nsw i32 %add, %5 + %6 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %d = getelementptr inbounds %struct.fourmem, %struct.fourmem* %6, i32 0, i32 3 + %7 = load i32, i32* %d, align 4 + %add2 = add nsw i32 %add1, %7 + store i32 %add2, i32* %S, align 4 + %8 = load i32, i32* %S, align 4 + ret i32 %8 +} + +attributes #0 = { noinline norecurse ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { noinline nounwind ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{!"clang version 11.0.0 (https://github.com/teamiceberg/llvm-project.git 1fb9041df0182c3e582bfcb5875e6af743eab0a1)"} \ No newline at end of file diff --git a/llvm/test/Transforms/ArgumentPromotion/fourmember-struct-promote-INTMAX.ll b/llvm/test/Transforms/ArgumentPromotion/fourmember-struct-promote-INTMAX.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/ArgumentPromotion/fourmember-struct-promote-INTMAX.ll @@ -0,0 +1,91 @@ +; RUN: opt < %s -basic-aa -mem2reg -argpromotion -mem2reg -numargspromoted=2147483647 -S | FileCheck %s + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +%struct.fourmem = type { i32, i32, i32, i32 } + +; Function Attrs: noinline norecurse ssp uwtable +define i32 @main() #0 { +; CHECK-LABEL: define {{[^@]+}}@main() +; CHECK-NEXT: entry: +; CHECK-NEXT: [[F:%.*]] = alloca {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 0 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 1 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 2 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 3 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: %{{.*}} = call i32 @{{.*}}fourmem(i32 [[F]].idx{{.*}}.val, i32 [[F]].idx{{.*}}.val, i32 [[F]].idx{{.*}}.val, i32 [[F]].idx{{.*}}.val) +; CHECK-NEXT: ret i32 0 +; +entry: + %retval = alloca i32, align 4 + %four = alloca %struct.fourmem, align 4 + %T = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + %a = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 0 + store i32 1, i32* %a, align 4 + %b = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 1 + store i32 2, i32* %b, align 4 + %c = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 2 + store i32 3, i32* %c, align 4 + %d = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 3 + store i32 4, i32* %d, align 4 + %call = call i32 @_ZL6calleeP7fourmem(%struct.fourmem* %four) + store i32 %call, i32* %T, align 4 + ret i32 0 +} + +; Function Attrs: noinline nounwind ssp uwtable +define internal i32 @_ZL6calleeP7fourmem(%struct.fourmem* %t) #1 { +; CHECK-LABEL: define {{[^@]+}}@{{.*}}fourmem +; CHECK-SAME: (i32 %t.0.{{.*}}.val, i32 %t.0.{{.*}}.val, i32 %t.0.{{.*}}.val, i32 %t.0.{{.*}}.val) +; CHECK-NEXT: entry: +; CHECK-NEXT: %add{{.*}} = add nsw i32 {{.*}}, {{.*}} +; CHECK-NEXT: %add{{.*}} = add nsw i32 {{.*}}, {{.*}} +; CHECK-NEXT: %add{{.*}} = add nsw i32 {{.*}}, {{.*}} +; CHECK-NEXT: ret i32 %{{.*}} +; +entry: + %t.addr = alloca %struct.fourmem*, align 8 + %S = alloca i32, align 4 + store %struct.fourmem* %t, %struct.fourmem** %t.addr, align 8 + %0 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %a = getelementptr inbounds %struct.fourmem, %struct.fourmem* %0, i32 0, i32 0 + %1 = load i32, i32* %a, align 4 + %2 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %b = getelementptr inbounds %struct.fourmem, %struct.fourmem* %2, i32 0, i32 1 + %3 = load i32, i32* %b, align 4 + %add = add nsw i32 %1, %3 + %4 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %c = getelementptr inbounds %struct.fourmem, %struct.fourmem* %4, i32 0, i32 2 + %5 = load i32, i32* %c, align 4 + %add1 = add nsw i32 %add, %5 + %6 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %d = getelementptr inbounds %struct.fourmem, %struct.fourmem* %6, i32 0, i32 3 + %7 = load i32, i32* %d, align 4 + %add2 = add nsw i32 %add1, %7 + store i32 %add2, i32* %S, align 4 + %8 = load i32, i32* %S, align 4 + ret i32 %8 +} + +attributes #0 = { noinline norecurse ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { noinline nounwind ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{!"clang version 11.0.0 (https://github.com/teamiceberg/llvm-project.git 1fb9041df0182c3e582bfcb5875e6af743eab0a1)"} diff --git a/llvm/test/Transforms/ArgumentPromotion/fourmember-struct-promote-ZERO.ll b/llvm/test/Transforms/ArgumentPromotion/fourmember-struct-promote-ZERO.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/ArgumentPromotion/fourmember-struct-promote-ZERO.ll @@ -0,0 +1,91 @@ +; RUN: opt < %s -basic-aa -mem2reg -argpromotion -mem2reg -numargspromoted=0 -S | FileCheck %s + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +%struct.fourmem = type { i32, i32, i32, i32 } + +; Function Attrs: noinline norecurse ssp uwtable +define i32 @main() #0 { +; CHECK-LABEL: define {{[^@]+}}@main() +; CHECK-NEXT: entry: +; CHECK-NEXT: [[F:%.*]] = alloca {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: {{%.*}} = getelementptr {{.*}} +; CHECK-NEXT: store {{.*}} +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 0 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 1 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 2 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: [[F]].idx{{.*}} = getelementptr %struct.fourmem, %struct.fourmem* [[F]], i64 0, i32 3 +; CHECK-NEXT: [[F]].idx{{.*}}.val = load i32, i32* [[F]].idx{{.*}}, align 4 +; CHECK-NEXT: %{{.*}} = call i32 @{{.*}}fourmem(i32 [[F]].idx{{.*}}.val, i32 [[F]].idx{{.*}}.val, i32 [[F]].idx{{.*}}.val, i32 [[F]].idx{{.*}}.val) +; CHECK-NEXT: ret i32 0 +; +entry: + %retval = alloca i32, align 4 + %four = alloca %struct.fourmem, align 4 + %T = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + %a = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 0 + store i32 1, i32* %a, align 4 + %b = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 1 + store i32 2, i32* %b, align 4 + %c = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 2 + store i32 3, i32* %c, align 4 + %d = getelementptr inbounds %struct.fourmem, %struct.fourmem* %four, i32 0, i32 3 + store i32 4, i32* %d, align 4 + %call = call i32 @_ZL6calleeP7fourmem(%struct.fourmem* %four) + store i32 %call, i32* %T, align 4 + ret i32 0 +} + +; Function Attrs: noinline nounwind ssp uwtable +define internal i32 @_ZL6calleeP7fourmem(%struct.fourmem* %t) #1 { +; CHECK-LABEL: define {{[^@]+}}@{{.*}}fourmem +; CHECK-SAME: (i32 %t.0.{{.*}}.val, i32 %t.0.{{.*}}.val, i32 %t.0.{{.*}}.val, i32 %t.0.{{.*}}.val) +; CHECK-NEXT: entry: +; CHECK-NEXT: %add{{.*}} = add nsw i32 {{.*}}, {{.*}} +; CHECK-NEXT: %add{{.*}} = add nsw i32 {{.*}}, {{.*}} +; CHECK-NEXT: %add{{.*}} = add nsw i32 {{.*}}, {{.*}} +; CHECK-NEXT: ret i32 %{{.*}} +; +entry: + %t.addr = alloca %struct.fourmem*, align 8 + %S = alloca i32, align 4 + store %struct.fourmem* %t, %struct.fourmem** %t.addr, align 8 + %0 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %a = getelementptr inbounds %struct.fourmem, %struct.fourmem* %0, i32 0, i32 0 + %1 = load i32, i32* %a, align 4 + %2 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %b = getelementptr inbounds %struct.fourmem, %struct.fourmem* %2, i32 0, i32 1 + %3 = load i32, i32* %b, align 4 + %add = add nsw i32 %1, %3 + %4 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %c = getelementptr inbounds %struct.fourmem, %struct.fourmem* %4, i32 0, i32 2 + %5 = load i32, i32* %c, align 4 + %add1 = add nsw i32 %add, %5 + %6 = load %struct.fourmem*, %struct.fourmem** %t.addr, align 8 + %d = getelementptr inbounds %struct.fourmem, %struct.fourmem* %6, i32 0, i32 3 + %7 = load i32, i32* %d, align 4 + %add2 = add nsw i32 %add1, %7 + store i32 %add2, i32* %S, align 4 + %8 = load i32, i32* %S, align 4 + ret i32 %8 +} + +attributes #0 = { noinline norecurse ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { noinline nounwind ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{!"clang version 11.0.0 (https://github.com/teamiceberg/llvm-project.git 1fb9041df0182c3e582bfcb5875e6af743eab0a1)"}