[clang] [IPSCCP] Variable not visible at Og. (PR #66745)
https://github.com/jryans edited https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og. (PR #66745)
https://github.com/CarlosAlbertoEnciso updated https://github.com/llvm/llvm-project/pull/66745 >From b24943f63025822a5c5ba90c4a7b47f7123ec4db Mon Sep 17 00:00:00 2001 From: Carlos Alberto Enciso Date: Mon, 18 Sep 2023 12:29:17 +0100 Subject: [PATCH 1/4] [IPSCCP] Variable not visible at Og: https://bugs.llvm.org/show_bug.cgi?id=51559 https://github.com/llvm/llvm-project/issues/50901 IPSCCP pass removes the global variable and does not create a constant expression for the initializer value. --- llvm/lib/Transforms/IPO/SCCP.cpp | 47 +++ llvm/test/Transforms/SCCP/pr50901.ll | 184 +++ 2 files changed, 231 insertions(+) create mode 100644 llvm/test/Transforms/SCCP/pr50901.ll diff --git a/llvm/lib/Transforms/IPO/SCCP.cpp b/llvm/lib/Transforms/IPO/SCCP.cpp index 84f5bbf7039416b..e09769e00148143 100644 --- a/llvm/lib/Transforms/IPO/SCCP.cpp +++ b/llvm/lib/Transforms/IPO/SCCP.cpp @@ -22,6 +22,7 @@ #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/AttributeMask.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ModRef.h" @@ -371,6 +372,52 @@ static bool runIPSCCP( StoreInst *SI = cast(GV->user_back()); SI->eraseFromParent(); } + +// Try to create a debug constant expression for the glbal variable +// initializer value. +SmallVector GVEs; +GV->getDebugInfo(GVEs); +if (GVEs.size() == 1) { + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = dyn_cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue(); Temp.has_value()) + // Transform a signed optional to unsigned optional. + InitIntOpt = (uint64_t)Temp.value(); +return DIB.createConstantValueExpression(InitIntOpt.value()); + }; + + const Constant *CV = GV->getInitializer(); + Type *Ty = GV->getValueType(); + if (Ty->isIntegerTy()) { +GVEs[0]->replaceOperandWith(1, createIntExpression(CV)); + } else if (Ty->isFloatTy() || Ty->isDoubleTy()) { +const APFloat &APF = dyn_cast(CV)->getValueAPF(); +DIExpression *NewExpr = DIB.createConstantValueExpression( +APF.bitcastToAPInt().getZExtValue()); +GVEs[0]->replaceOperandWith(1, NewExpr); + } else if (Ty->isPointerTy()) { +if (isa(CV)) { + GVEs[0]->replaceOperandWith(1, DIB.createConstantValueExpression(0)); +} else { + if (const ConstantExpr *CE = dyn_cast(CV)) { +if (CE->getNumOperands() == 1) { + const Value *V = CE->getOperand(0); + const Constant *CV = dyn_cast(V); + if (CV && !isa(CV)) +if (const ConstantInt *CI = dyn_cast(CV)) + GVEs[0]->replaceOperandWith(1, createIntExpression(CI)); +} + } +} + } +} + MadeChanges = true; M.eraseGlobalVariable(GV); ++NumGlobalConst; diff --git a/llvm/test/Transforms/SCCP/pr50901.ll b/llvm/test/Transforms/SCCP/pr50901.ll new file mode 100644 index 000..56961d2e32db41c --- /dev/null +++ b/llvm/test/Transforms/SCCP/pr50901.ll @@ -0,0 +1,184 @@ +; RUN: opt -passes=ipsccp -S -o - < %s | FileCheck %s + +; Global variables g_11, g_22, g_33, g_44, g_55, g_66 and g_77 +; are not visible in the debugger. + +; 1 int g_1 = -4; +; 2 float g_2 = 4.44; +; 3 char g_3 = 'a'; +; 4 unsigned g_4 = 4; +; 5 bool g_5 = true; +; 6 int *g_6 = nullptr; +; 7 float*g_7 = nullptr; +; 8 +; 9 static int g_11 = -5; +; 10 static float g_22 = 5.55; +; 11 static char g_33 = 'b'; +; 12 static unsigned g_44 = 5; +; 13 static bool g_55 = true; +; 14 static int *g_66 = nullptr; +; 15 static float*g_77 = (float *)(55 + 15); +; 16 +; 17 void bar() { +; 18 g_1 = g_11; +; 19 g_2 = g_22; +; 20 g_3 = g_33; +; 21 g_4 = g_44; +; 22 g_5 = g_55; +; 23 g_6 = g_66; +; 24 g_7 = g_77; +; 25 } +; 26 +; 27 int main() { +; 28 { +; 29 bar(); +; 30 } +; 31 } + +; CHECK: ![[G1:[0-9]+]] = !DIGlobalVariableExpression(var: ![[DBG1:[0-9]+]], expr: !DIExpression(DW_OP_constu, 18446744073709551611, DW_OP_stack_value)) +; CHECK-DAG: ![[DBG1]] = distinct !DIGlobalVariable(name: "g_11", {{.*}} +; CHECK: ![[G2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[DBG2:[0-9]+]], expr: !DIExpression(DW_OP_constu, 1085381018, DW_OP_stack_value)) +; CHECK-DAG: ![[DBG2]] = distinct !DIGlobalVariable(name: "g_22", {{.*}} +; CHECK: ![[G3:[0-9]+]] = !DIGlobalVariableExpression(var: ![[DBG3:[0-9]+]], expr: !DIExpression(DW_OP_constu, 98, DW_OP_stack_value)) +; CHECK-DAG: ![[DBG3]] = distin
[clang] [IPSCCP] Variable not visible at Og. (PR #66745)
https://github.com/jryans edited https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og. (PR #66745)
@@ -106,14 +107,71 @@ static void findReturnsToZap(Function &F, } } -static bool runIPSCCP( -Module &M, const DataLayout &DL, FunctionAnalysisManager *FAM, -std::function GetTLI, -std::function GetTTI, -std::function GetAC, -std::function GetDT, -std::function GetBFI, -bool IsFuncSpecEnabled) { +static void createDebugConstantExpression(Module &M, GlobalVariable *GV) { + SmallVector GVEs; + GV->getDebugInfo(GVEs); + if (GVEs.size() != 1) +return; + + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntegerExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue()) + // Transform a signed optional to unsigned optional. + InitIntOpt = static_cast(*Temp); felipepiovezan wrote: Looking at this again, isn't this the equivalent of always doing a sign extension? We are basically saying: if this starts with a zero, add zeros; if this starts with a one, add ones. Unless I am missing something, this code could be: ``` if (std::optional InitIntOpt = API.trySExtValue()) return DIB.createConstantValueExpression(static_cast(*InitIntOpt)) return nullptr; ``` https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og. (PR #66745)
@@ -106,14 +107,71 @@ static void findReturnsToZap(Function &F, } } -static bool runIPSCCP( -Module &M, const DataLayout &DL, FunctionAnalysisManager *FAM, -std::function GetTLI, -std::function GetTTI, -std::function GetAC, -std::function GetDT, -std::function GetBFI, -bool IsFuncSpecEnabled) { +static void createDebugConstantExpression(Module &M, GlobalVariable *GV) { + SmallVector GVEs; + GV->getDebugInfo(GVEs); + if (GVEs.size() != 1) +return; + + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntegerExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue()) + // Transform a signed optional to unsigned optional. + InitIntOpt = static_cast(*Temp); +return InitIntOpt ? DIB.createConstantValueExpression(InitIntOpt.value()) + : nullptr; + }; + + const Constant *CV = GV->getInitializer(); + Type *Ty = GV->getValueType(); + if (Ty->isIntegerTy()) { +DIExpression *InitExpr = createIntegerExpression(CV); +if (InitExpr) + GVEs[0]->replaceOperandWith(1, InitExpr); +return; + } + + if (Ty->isFloatTy() || Ty->isDoubleTy()) { +const APFloat &APF = cast(CV)->getValueAPF(); +GVEs[0]->replaceOperandWith(1, DIB.createConstantValueExpression( + APF.bitcastToAPInt().getZExtValue())); +return; + } + + if (!Ty->isPointerTy()) +return; + + if (isa(CV)) { +GVEs[0]->replaceOperandWith(1, DIB.createConstantValueExpression(0)); +return; + } + if (const ConstantExpr *CE = dyn_cast(CV); + CE->getNumOperands() == 1) { +const Value *V = CE->getOperand(0); +const Constant *CV = dyn_cast(V); +if (CV && !isa(CV); felipepiovezan wrote: Yeah, I believe the intent here would be: ``` if (auto CI = dyn_cast_or_null(V)) { ... } ``` Note that `!isa(CV)` is not necessary: a global value is always a pointer, therefore it cannot be a `ConstantInt` https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og. (PR #66745)
@@ -106,14 +107,71 @@ static void findReturnsToZap(Function &F, } } -static bool runIPSCCP( -Module &M, const DataLayout &DL, FunctionAnalysisManager *FAM, -std::function GetTLI, -std::function GetTTI, -std::function GetAC, -std::function GetDT, -std::function GetBFI, -bool IsFuncSpecEnabled) { +static void createDebugConstantExpression(Module &M, GlobalVariable *GV) { + SmallVector GVEs; + GV->getDebugInfo(GVEs); + if (GVEs.size() != 1) +return; + + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntegerExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue()) + // Transform a signed optional to unsigned optional. + InitIntOpt = static_cast(*Temp); +return InitIntOpt ? DIB.createConstantValueExpression(InitIntOpt.value()) + : nullptr; + }; + + const Constant *CV = GV->getInitializer(); + Type *Ty = GV->getValueType(); + if (Ty->isIntegerTy()) { +DIExpression *InitExpr = createIntegerExpression(CV); +if (InitExpr) + GVEs[0]->replaceOperandWith(1, InitExpr); +return; + } + + if (Ty->isFloatTy() || Ty->isDoubleTy()) { +const APFloat &APF = cast(CV)->getValueAPF(); +GVEs[0]->replaceOperandWith(1, DIB.createConstantValueExpression( + APF.bitcastToAPInt().getZExtValue())); +return; + } + + if (!Ty->isPointerTy()) +return; + + if (isa(CV)) { +GVEs[0]->replaceOperandWith(1, DIB.createConstantValueExpression(0)); +return; + } + if (const ConstantExpr *CE = dyn_cast(CV); + CE->getNumOperands() == 1) { +const Value *V = CE->getOperand(0); +const Constant *CV = dyn_cast(V); +if (CV && !isa(CV); dwblaikie wrote: I'm not sure this does what's intended (assuming the intent is that the `CV && !isa` part is meant to be part of the boolean condition of the `if` as well as the `CI` init) - these boolean expressions would have no effect, right? (the second part of the if, after the semicolon, would be the only condition? https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og. (PR #66745)
@@ -106,14 +107,71 @@ static void findReturnsToZap(Function &F, } } -static bool runIPSCCP( -Module &M, const DataLayout &DL, FunctionAnalysisManager *FAM, -std::function GetTLI, -std::function GetTTI, -std::function GetAC, -std::function GetDT, -std::function GetBFI, -bool IsFuncSpecEnabled) { +static void createDebugConstantExpression(Module &M, GlobalVariable *GV) { + SmallVector GVEs; + GV->getDebugInfo(GVEs); + if (GVEs.size() != 1) +return; + + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntegerExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue()) + // Transform a signed optional to unsigned optional. + InitIntOpt = static_cast(*Temp); +return InitIntOpt ? DIB.createConstantValueExpression(InitIntOpt.value()) + : nullptr; + }; + + const Constant *CV = GV->getInitializer(); + Type *Ty = GV->getValueType(); + if (Ty->isIntegerTy()) { +DIExpression *InitExpr = createIntegerExpression(CV); +if (InitExpr) + GVEs[0]->replaceOperandWith(1, InitExpr); +return; + } + + if (Ty->isFloatTy() || Ty->isDoubleTy()) { +const APFloat &APF = cast(CV)->getValueAPF(); +GVEs[0]->replaceOperandWith(1, DIB.createConstantValueExpression( + APF.bitcastToAPInt().getZExtValue())); +return; + } + + if (!Ty->isPointerTy()) +return; + + if (isa(CV)) { +GVEs[0]->replaceOperandWith(1, DIB.createConstantValueExpression(0)); +return; + } + if (const ConstantExpr *CE = dyn_cast(CV); dwblaikie wrote: This is probably problematic too - the initializer part of the `if` isn't part of the boolean condition - so the `CE` would be unconditionally dereferenced in the `CE->getNumOperands()` call - so either the `CE` init should use `cast`, not `dyn_cast` - or the condition needs to be `CE && CE->getNumOperands() ...` (or nested `if`s) https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og: (PR #66745)
@@ -371,6 +372,52 @@ static bool runIPSCCP( StoreInst *SI = cast(GV->user_back()); SI->eraseFromParent(); } + +// Try to create a debug constant expression for the glbal variable +// initializer value. +SmallVector GVEs; +GV->getDebugInfo(GVEs); +if (GVEs.size() == 1) { + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = dyn_cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue(); Temp.has_value()) + // Transform a signed optional to unsigned optional. + InitIntOpt = (uint64_t)Temp.value(); +return DIB.createConstantValueExpression(InitIntOpt.value()); + }; + + const Constant *CV = GV->getInitializer(); + Type *Ty = GV->getValueType(); + if (Ty->isIntegerTy()) { +GVEs[0]->replaceOperandWith(1, createIntExpression(CV)); + } else if (Ty->isFloatTy() || Ty->isDoubleTy()) { +const APFloat &APF = dyn_cast(CV)->getValueAPF(); +DIExpression *NewExpr = DIB.createConstantValueExpression( +APF.bitcastToAPInt().getZExtValue()); +GVEs[0]->replaceOperandWith(1, NewExpr); + } else if (Ty->isPointerTy()) { +if (isa(CV)) { + GVEs[0]->replaceOperandWith(1, DIB.createConstantValueExpression(0)); +} else { + if (const ConstantExpr *CE = dyn_cast(CV)) { +if (CE->getNumOperands() == 1) { + const Value *V = CE->getOperand(0); + const Constant *CV = dyn_cast(V); + if (CV && !isa(CV)) +if (const ConstantInt *CI = dyn_cast(CV)) + GVEs[0]->replaceOperandWith(1, createIntExpression(CI)); +} + } +} + } +} CarlosAlbertoEnciso wrote: Replaced with your suggested change. https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og: (PR #66745)
@@ -371,6 +372,52 @@ static bool runIPSCCP( StoreInst *SI = cast(GV->user_back()); SI->eraseFromParent(); } + +// Try to create a debug constant expression for the glbal variable +// initializer value. +SmallVector GVEs; +GV->getDebugInfo(GVEs); +if (GVEs.size() == 1) { + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = dyn_cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue(); Temp.has_value()) + // Transform a signed optional to unsigned optional. + InitIntOpt = (uint64_t)Temp.value(); +return DIB.createConstantValueExpression(InitIntOpt.value()); + }; + + const Constant *CV = GV->getInitializer(); + Type *Ty = GV->getValueType(); + if (Ty->isIntegerTy()) { +GVEs[0]->replaceOperandWith(1, createIntExpression(CV)); + } else if (Ty->isFloatTy() || Ty->isDoubleTy()) { +const APFloat &APF = dyn_cast(CV)->getValueAPF(); CarlosAlbertoEnciso wrote: Changed to `cast` https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og: (PR #66745)
@@ -371,6 +372,52 @@ static bool runIPSCCP( StoreInst *SI = cast(GV->user_back()); SI->eraseFromParent(); } + +// Try to create a debug constant expression for the glbal variable +// initializer value. +SmallVector GVEs; +GV->getDebugInfo(GVEs); +if (GVEs.size() == 1) { + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = dyn_cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue(); Temp.has_value()) + // Transform a signed optional to unsigned optional. + InitIntOpt = (uint64_t)Temp.value(); +return DIB.createConstantValueExpression(InitIntOpt.value()); + }; + + const Constant *CV = GV->getInitializer(); + Type *Ty = GV->getValueType(); + if (Ty->isIntegerTy()) { +GVEs[0]->replaceOperandWith(1, createIntExpression(CV)); CarlosAlbertoEnciso wrote: The function `replaceOperandWith` takes that into consideration. https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og: (PR #66745)
@@ -371,6 +372,52 @@ static bool runIPSCCP( StoreInst *SI = cast(GV->user_back()); SI->eraseFromParent(); } + +// Try to create a debug constant expression for the glbal variable +// initializer value. +SmallVector GVEs; +GV->getDebugInfo(GVEs); +if (GVEs.size() == 1) { + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = dyn_cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue(); Temp.has_value()) + // Transform a signed optional to unsigned optional. + InitIntOpt = (uint64_t)Temp.value(); +return DIB.createConstantValueExpression(InitIntOpt.value()); CarlosAlbertoEnciso wrote: Changed to use `cast`. https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og: (PR #66745)
@@ -371,6 +372,52 @@ static bool runIPSCCP( StoreInst *SI = cast(GV->user_back()); SI->eraseFromParent(); } + +// Try to create a debug constant expression for the glbal variable +// initializer value. +SmallVector GVEs; +GV->getDebugInfo(GVEs); +if (GVEs.size() == 1) { + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = dyn_cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue(); Temp.has_value()) + // Transform a signed optional to unsigned optional. + InitIntOpt = (uint64_t)Temp.value(); CarlosAlbertoEnciso wrote: Using instead `static_cast` https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og: (PR #66745)
@@ -371,6 +372,52 @@ static bool runIPSCCP( StoreInst *SI = cast(GV->user_back()); SI->eraseFromParent(); } + +// Try to create a debug constant expression for the glbal variable +// initializer value. CarlosAlbertoEnciso wrote: Moving the code to a helper function. https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [IPSCCP] Variable not visible at Og: (PR #66745)
https://github.com/CarlosAlbertoEnciso updated https://github.com/llvm/llvm-project/pull/66745 >From b24943f63025822a5c5ba90c4a7b47f7123ec4db Mon Sep 17 00:00:00 2001 From: Carlos Alberto Enciso Date: Mon, 18 Sep 2023 12:29:17 +0100 Subject: [PATCH] [IPSCCP] Variable not visible at Og: https://bugs.llvm.org/show_bug.cgi?id=51559 https://github.com/llvm/llvm-project/issues/50901 IPSCCP pass removes the global variable and does not create a constant expression for the initializer value. --- llvm/lib/Transforms/IPO/SCCP.cpp | 47 +++ llvm/test/Transforms/SCCP/pr50901.ll | 184 +++ 2 files changed, 231 insertions(+) create mode 100644 llvm/test/Transforms/SCCP/pr50901.ll diff --git a/llvm/lib/Transforms/IPO/SCCP.cpp b/llvm/lib/Transforms/IPO/SCCP.cpp index 84f5bbf7039416b..e09769e00148143 100644 --- a/llvm/lib/Transforms/IPO/SCCP.cpp +++ b/llvm/lib/Transforms/IPO/SCCP.cpp @@ -22,6 +22,7 @@ #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/AttributeMask.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ModRef.h" @@ -371,6 +372,52 @@ static bool runIPSCCP( StoreInst *SI = cast(GV->user_back()); SI->eraseFromParent(); } + +// Try to create a debug constant expression for the glbal variable +// initializer value. +SmallVector GVEs; +GV->getDebugInfo(GVEs); +if (GVEs.size() == 1) { + DIBuilder DIB(M); + + // Create integer constant expression. + auto createIntExpression = [&DIB](const Constant *CV) -> DIExpression * { +const APInt &API = dyn_cast(CV)->getValue(); +std::optional InitIntOpt; +if (API.isNonNegative()) + InitIntOpt = API.tryZExtValue(); +else if (auto Temp = API.trySExtValue(); Temp.has_value()) + // Transform a signed optional to unsigned optional. + InitIntOpt = (uint64_t)Temp.value(); +return DIB.createConstantValueExpression(InitIntOpt.value()); + }; + + const Constant *CV = GV->getInitializer(); + Type *Ty = GV->getValueType(); + if (Ty->isIntegerTy()) { +GVEs[0]->replaceOperandWith(1, createIntExpression(CV)); + } else if (Ty->isFloatTy() || Ty->isDoubleTy()) { +const APFloat &APF = dyn_cast(CV)->getValueAPF(); +DIExpression *NewExpr = DIB.createConstantValueExpression( +APF.bitcastToAPInt().getZExtValue()); +GVEs[0]->replaceOperandWith(1, NewExpr); + } else if (Ty->isPointerTy()) { +if (isa(CV)) { + GVEs[0]->replaceOperandWith(1, DIB.createConstantValueExpression(0)); +} else { + if (const ConstantExpr *CE = dyn_cast(CV)) { +if (CE->getNumOperands() == 1) { + const Value *V = CE->getOperand(0); + const Constant *CV = dyn_cast(V); + if (CV && !isa(CV)) +if (const ConstantInt *CI = dyn_cast(CV)) + GVEs[0]->replaceOperandWith(1, createIntExpression(CI)); +} + } +} + } +} + MadeChanges = true; M.eraseGlobalVariable(GV); ++NumGlobalConst; diff --git a/llvm/test/Transforms/SCCP/pr50901.ll b/llvm/test/Transforms/SCCP/pr50901.ll new file mode 100644 index 000..56961d2e32db41c --- /dev/null +++ b/llvm/test/Transforms/SCCP/pr50901.ll @@ -0,0 +1,184 @@ +; RUN: opt -passes=ipsccp -S -o - < %s | FileCheck %s + +; Global variables g_11, g_22, g_33, g_44, g_55, g_66 and g_77 +; are not visible in the debugger. + +; 1 int g_1 = -4; +; 2 float g_2 = 4.44; +; 3 char g_3 = 'a'; +; 4 unsigned g_4 = 4; +; 5 bool g_5 = true; +; 6 int *g_6 = nullptr; +; 7 float*g_7 = nullptr; +; 8 +; 9 static int g_11 = -5; +; 10 static float g_22 = 5.55; +; 11 static char g_33 = 'b'; +; 12 static unsigned g_44 = 5; +; 13 static bool g_55 = true; +; 14 static int *g_66 = nullptr; +; 15 static float*g_77 = (float *)(55 + 15); +; 16 +; 17 void bar() { +; 18 g_1 = g_11; +; 19 g_2 = g_22; +; 20 g_3 = g_33; +; 21 g_4 = g_44; +; 22 g_5 = g_55; +; 23 g_6 = g_66; +; 24 g_7 = g_77; +; 25 } +; 26 +; 27 int main() { +; 28 { +; 29 bar(); +; 30 } +; 31 } + +; CHECK: ![[G1:[0-9]+]] = !DIGlobalVariableExpression(var: ![[DBG1:[0-9]+]], expr: !DIExpression(DW_OP_constu, 18446744073709551611, DW_OP_stack_value)) +; CHECK-DAG: ![[DBG1]] = distinct !DIGlobalVariable(name: "g_11", {{.*}} +; CHECK: ![[G2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[DBG2:[0-9]+]], expr: !DIExpression(DW_OP_constu, 1085381018, DW_OP_stack_value)) +; CHECK-DAG: ![[DBG2]] = distinct !DIGlobalVariable(name: "g_22", {{.*}} +; CHECK: ![[G3:[0-9]+]] = !DIGlobalVariableExpression(var: ![[DBG3:[0-9]+]], expr: !DIExpression(DW_OP_constu, 98, DW_OP_stack_value)) +; CHECK-DAG: ![[DBG3]] = distinct !
[clang] [IPSCCP] Variable not visible at Og: (PR #66745)
https://github.com/jryans edited https://github.com/llvm/llvm-project/pull/66745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits