Skip to content

Commit 2b524f1

Browse files
[IPSCCP] Variable not visible at Og:
https://bugs.llvm.org/show_bug.cgi?id=51559 #50901 IPSCCP pass removes the global variable and does not create a constant expression for the initializer value. Address reviewers comments: - Refactor the new code into a helper function. - Use early returns to reduce nested ifs. - Remove C-style casts. - Add validation to detect posible nullopt. - Collapse conditions in a single if. - Remove 'has_value'. - Additional if condition simplifications. - Move new logic into a general helper function. - Move new logic to the 'Dbg Intrinsic utilities'" section. - Pass 'Constant' and 'Type' as references. - Remove extra whitespace differences (incorrect clang-format). - Use 'Instruction::IntToPtr' with pointer types. - Reduce lit test case. - Add unittests for the new helper function.
1 parent 84ad848 commit 2b524f1

File tree

3 files changed

+131
-52
lines changed

3 files changed

+131
-52
lines changed

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3101,14 +3101,12 @@ DIExpression *llvm::getExpressionForConstant(DIBuilder &DIB, const Constant &C,
31013101
if (isa<ConstantPointerNull>(C))
31023102
return DIB.createConstantValueExpression(0);
31033103

3104-
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(&C)) {
3105-
if (CE->getNumOperands() == 1) {
3104+
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(&C))
3105+
if (CE->getOpcode() == Instruction::IntToPtr) {
31063106
const Value *V = CE->getOperand(0);
3107-
if (auto CI = dyn_cast_or_null<ConstantInt>(V)) {
3107+
if (auto CI = dyn_cast_or_null<ConstantInt>(V))
31083108
return createIntegerExpression(*CI);
3109-
}
31103109
}
3111-
}
31123110
return nullptr;
31133111
}
31143112

llvm/test/Transforms/SCCP/pr50901.ll

Lines changed: 17 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@
5050
; CHECK: ![[G7:[0-9]+]] = !DIGlobalVariableExpression(var: ![[DBG7:[0-9]+]], expr: !DIExpression(DW_OP_constu, 70, DW_OP_stack_value))
5151
; CHECK-DAG: ![[DBG7]] = distinct !DIGlobalVariable(name: "g_77", {{.*}}
5252

53-
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
54-
target triple = "x86_64-pc-linux-gnu"
55-
5653
@g_1 = dso_local global i32 -4, align 4, !dbg !0
5754
@g_2 = dso_local global float 0x4011C28F60000000, align 4, !dbg !8
5855
@g_3 = dso_local global i8 97, align 1, !dbg !10
@@ -70,23 +67,23 @@ target triple = "x86_64-pc-linux-gnu"
7067

7168
define dso_local void @_Z3barv() !dbg !46 {
7269
entry:
73-
%0 = load i32, ptr @_ZL4g_11, align 4, !dbg !49, !tbaa !50
74-
store i32 %0, ptr @g_1, align 4, !dbg !54, !tbaa !50
75-
%1 = load float, ptr @_ZL4g_22, align 4, !dbg !55, !tbaa !56
76-
store float %1, ptr @g_2, align 4, !dbg !58, !tbaa !56
77-
%2 = load i8, ptr @_ZL4g_33, align 1, !dbg !59, !tbaa !60
78-
store i8 %2, ptr @g_3, align 1, !dbg !61, !tbaa !60
79-
%3 = load i32, ptr @_ZL4g_44, align 4, !dbg !62, !tbaa !50
80-
store i32 %3, ptr @g_4, align 4, !dbg !63, !tbaa !50
81-
%4 = load i8, ptr @_ZL4g_55, align 1, !dbg !64, !tbaa !65, !range !67, !noundef !68
82-
%tobool = trunc i8 %4 to i1, !dbg !64
83-
%frombool = zext i1 %tobool to i8, !dbg !69
84-
store i8 %frombool, ptr @g_5, align 1, !dbg !69, !tbaa !65
85-
%5 = load ptr, ptr @_ZL4g_66, align 8, !dbg !70, !tbaa !71
86-
store ptr %5, ptr @g_6, align 8, !dbg !73, !tbaa !71
87-
%6 = load ptr, ptr @_ZL4g_77, align 8, !dbg !74, !tbaa !71
88-
store ptr %6, ptr @g_7, align 8, !dbg !75, !tbaa !71
89-
ret void, !dbg !76
70+
%0 = load i32, ptr @_ZL4g_11, align 4, !dbg !59
71+
store i32 %0, ptr @g_1, align 4, !dbg !59
72+
%1 = load float, ptr @_ZL4g_22, align 4, !dbg !59
73+
store float %1, ptr @g_2, align 4, !dbg !59
74+
%2 = load i8, ptr @_ZL4g_33, align 1, !dbg !59
75+
store i8 %2, ptr @g_3, align 1, !dbg !59
76+
%3 = load i32, ptr @_ZL4g_44, align 4, !dbg !59
77+
store i32 %3, ptr @g_4, align 4, !dbg !59
78+
%4 = load i8, ptr @_ZL4g_55, align 1, !dbg !59
79+
%tobool = trunc i8 %4 to i1, !dbg !59
80+
%frombool = zext i1 %tobool to i8, !dbg !59
81+
store i8 %frombool, ptr @g_5, align 1, !dbg !59
82+
%5 = load ptr, ptr @_ZL4g_66, align 8, !dbg !59
83+
store ptr %5, ptr @g_6, align 8, !dbg !59
84+
%6 = load ptr, ptr @_ZL4g_77, align 8, !dbg !59
85+
store ptr %6, ptr @g_7, align 8, !dbg !59
86+
ret void, !dbg !59
9087
}
9188

9289
define dso_local noundef i32 @main() !dbg !77 {
@@ -148,34 +145,7 @@ entry:
148145
!46 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !3, file: !3, line: 17, type: !47, scopeLine: 17, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
149146
!47 = !DISubroutineType(types: !48)
150147
!48 = !{null}
151-
!49 = !DILocation(line: 18, column: 9, scope: !46)
152-
!50 = !{!51, !51, i64 0}
153-
!51 = !{!"int", !52, i64 0}
154-
!52 = !{!"omnipotent char", !53, i64 0}
155-
!53 = !{!"Simple C++ TBAA"}
156-
!54 = !DILocation(line: 18, column: 7, scope: !46)
157-
!55 = !DILocation(line: 19, column: 9, scope: !46)
158-
!56 = !{!57, !57, i64 0}
159-
!57 = !{!"float", !52, i64 0}
160-
!58 = !DILocation(line: 19, column: 7, scope: !46)
161148
!59 = !DILocation(line: 20, column: 9, scope: !46)
162-
!60 = !{!52, !52, i64 0}
163-
!61 = !DILocation(line: 20, column: 7, scope: !46)
164-
!62 = !DILocation(line: 21, column: 9, scope: !46)
165-
!63 = !DILocation(line: 21, column: 7, scope: !46)
166-
!64 = !DILocation(line: 22, column: 9, scope: !46)
167-
!65 = !{!66, !66, i64 0}
168-
!66 = !{!"bool", !52, i64 0}
169-
!67 = !{i8 0, i8 2}
170-
!68 = !{}
171-
!69 = !DILocation(line: 22, column: 7, scope: !46)
172-
!70 = !DILocation(line: 23, column: 9, scope: !46)
173-
!71 = !{!72, !72, i64 0}
174-
!72 = !{!"any pointer", !52, i64 0}
175-
!73 = !DILocation(line: 23, column: 7, scope: !46)
176-
!74 = !DILocation(line: 24, column: 9, scope: !46)
177-
!75 = !DILocation(line: 24, column: 7, scope: !46)
178-
!76 = !DILocation(line: 25, column: 1, scope: !46)
179149
!77 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 27, type: !78, scopeLine: 27, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
180150
!78 = !DISubroutineType(types: !79)
181151
!79 = !{!22}

llvm/unittests/Transforms/Utils/LocalTest.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,3 +1161,114 @@ TEST(Local, CanReplaceOperandWithVariable) {
11611161

11621162
BB0->dropAllReferences();
11631163
}
1164+
1165+
TEST(Local, ExpressionForConstant) {
1166+
LLVMContext Context;
1167+
Module M("test_module", Context);
1168+
DIBuilder DIB(M);
1169+
DIExpression *Expr = nullptr;
1170+
1171+
auto createExpression = [&](Constant *C, Type *Ty) -> DIExpression * {
1172+
EXPECT_NE(C, nullptr);
1173+
EXPECT_NE(Ty, nullptr);
1174+
EXPECT_EQ(C->getType(), Ty);
1175+
std::unique_ptr<GlobalVariable> GV = std::make_unique<GlobalVariable>(
1176+
Ty, false, GlobalValue::ExternalLinkage, C, "GV");
1177+
EXPECT_NE(GV, nullptr);
1178+
1179+
DIExpression *Expr = getExpressionForConstant(DIB, *GV->getInitializer(),
1180+
*GV->getValueType());
1181+
if (Expr) {
1182+
EXPECT_EQ(Expr->getNumElements(), 3u);
1183+
EXPECT_EQ(Expr->getElement(0), dwarf::DW_OP_constu);
1184+
EXPECT_EQ(Expr->getElement(2), dwarf::DW_OP_stack_value);
1185+
}
1186+
return Expr;
1187+
};
1188+
1189+
// Integer.
1190+
IntegerType *Int1Ty = Type::getInt1Ty(Context);
1191+
Expr = createExpression(ConstantInt::getTrue(Context), Int1Ty);
1192+
EXPECT_NE(Expr, nullptr);
1193+
EXPECT_EQ(Expr->getElement(1), 18446744073709551615);
1194+
1195+
Expr = createExpression(ConstantInt::getFalse(Context), Int1Ty);
1196+
EXPECT_NE(Expr, nullptr);
1197+
EXPECT_EQ(Expr->getElement(1), 0);
1198+
1199+
IntegerType *Int8Ty = Type::getInt8Ty(Context);
1200+
Expr = createExpression(ConstantInt::get(Int8Ty, 100), Int8Ty);
1201+
EXPECT_NE(Expr, nullptr);
1202+
EXPECT_EQ(Expr->getElement(1), 100);
1203+
1204+
IntegerType *Int16Ty = Type::getInt16Ty(Context);
1205+
Expr = createExpression(ConstantInt::getSigned(Int16Ty, -50), Int16Ty);
1206+
EXPECT_NE(Expr, nullptr);
1207+
EXPECT_EQ(Expr->getElement(1), -50);
1208+
1209+
IntegerType *Int32Ty = Type::getInt32Ty(Context);
1210+
Expr = createExpression(ConstantInt::get(Int32Ty, 0x7FFFFFFF), Int32Ty);
1211+
EXPECT_NE(Expr, nullptr);
1212+
EXPECT_EQ(Expr->getElement(1), 0x7FFFFFFF);
1213+
1214+
IntegerType *Int64Ty = Type::getInt64Ty(Context);
1215+
Expr =
1216+
createExpression(ConstantInt::get(Int64Ty, 0x7FFFFFFFFFFFFFFF), Int64Ty);
1217+
EXPECT_NE(Expr, nullptr);
1218+
EXPECT_EQ(Expr->getElement(1), 0x7FFFFFFFFFFFFFFF);
1219+
1220+
IntegerType *Int128Ty = Type::getInt128Ty(Context);
1221+
Expr = createExpression(ConstantInt::get(Int128Ty, 0x7FFFFFFFFFFFFFFF),
1222+
Int128Ty);
1223+
EXPECT_NE(Expr, nullptr);
1224+
EXPECT_EQ(Expr->getElement(1), 0x7FFFFFFFFFFFFFFF);
1225+
1226+
// Float.
1227+
Type *FloatTy = Type::getFloatTy(Context);
1228+
Expr = createExpression(ConstantFP::get(FloatTy, 5.55), FloatTy);
1229+
EXPECT_NE(Expr, nullptr);
1230+
EXPECT_EQ(Expr->getElement(1), 1085381018);
1231+
1232+
// Double.
1233+
Type *DoubleTy = Type::getDoubleTy(Context);
1234+
Expr = createExpression(ConstantFP::get(DoubleTy, -5.55), DoubleTy);
1235+
EXPECT_NE(Expr, nullptr);
1236+
EXPECT_EQ(Expr->getElement(1), 13841306799765140275);
1237+
1238+
// Pointer.
1239+
PointerType *PtrTy = PointerType::get(Context, 0);
1240+
Expr = createExpression(ConstantPointerNull::get(PtrTy), PtrTy);
1241+
EXPECT_NE(Expr, nullptr);
1242+
EXPECT_EQ(Expr->getElement(1), 0);
1243+
1244+
ConstantInt *K1 = ConstantInt::get(Type::getInt32Ty(Context), 1234);
1245+
Expr = createExpression(ConstantExpr::getIntToPtr(K1, PtrTy), PtrTy);
1246+
EXPECT_NE(Expr, nullptr);
1247+
EXPECT_EQ(Expr->getElement(1), 1234);
1248+
1249+
ConstantInt *K2 = ConstantInt::get(Type::getInt64Ty(Context), 5678);
1250+
Expr = createExpression(ConstantExpr::getIntToPtr(K2, PtrTy), PtrTy);
1251+
EXPECT_NE(Expr, nullptr);
1252+
EXPECT_EQ(Expr->getElement(1), 5678);
1253+
1254+
// Others.
1255+
Type *HalfTy = Type::getHalfTy(Context);
1256+
Expr = createExpression(ConstantFP::get(HalfTy, 32), HalfTy);
1257+
EXPECT_EQ(Expr, nullptr);
1258+
1259+
Type *BFloatTy = Type::getBFloatTy(Context);
1260+
Expr = createExpression(ConstantFP::get(BFloatTy, 32), BFloatTy);
1261+
EXPECT_EQ(Expr, nullptr);
1262+
1263+
Type *FP128Ty = Type::getFP128Ty(Context);
1264+
Expr = createExpression(ConstantFP::get(FP128Ty, 32), FP128Ty);
1265+
EXPECT_EQ(Expr, nullptr);
1266+
1267+
Type *X86_FP80Ty = Type::getX86_FP80Ty(Context);
1268+
Expr = createExpression(ConstantFP::get(X86_FP80Ty, 32), X86_FP80Ty);
1269+
EXPECT_EQ(Expr, nullptr);
1270+
1271+
Type *PPC_FP128Ty = Type::getPPC_FP128Ty(Context);
1272+
Expr = createExpression(ConstantFP::get(PPC_FP128Ty, 32), PPC_FP128Ty);
1273+
EXPECT_EQ(Expr, nullptr);
1274+
}

0 commit comments

Comments
 (0)