Skip to content

Commit 2d9759c

Browse files
committed
[GlobalOpt] Fix the load types when OptimizeGlobalAddressOfMalloc
Currently, in OptimizeGlobalAddressOfMalloc, the transformation for global loads assumes that they have the same Type. With the support of ConstantExpr (https://reviews.llvm.org/D106589), this may not be true any more (as seen in the test case), and we miss the code to handle this, This is to fix that. Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D107397
1 parent ba2be8d commit 2d9759c

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

llvm/lib/Transforms/IPO/GlobalOpt.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -967,9 +967,8 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
967967
}
968968
}
969969

970-
Constant *RepValue = NewGV;
971-
if (NewGV->getType() != GV->getValueType())
972-
RepValue = ConstantExpr::getBitCast(RepValue, GV->getValueType());
970+
SmallPtrSet<Constant *, 1> RepValues;
971+
RepValues.insert(NewGV);
973972

974973
// If there is a comparison against null, we will insert a global bool to
975974
// keep track of whether the global was initialized yet or not.
@@ -1001,7 +1000,9 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
10011000
Use &LoadUse = *LI->use_begin();
10021001
ICmpInst *ICI = dyn_cast<ICmpInst>(LoadUse.getUser());
10031002
if (!ICI) {
1004-
LoadUse = RepValue;
1003+
auto *CE = ConstantExpr::getBitCast(NewGV, LI->getType());
1004+
RepValues.insert(CE);
1005+
LoadUse.set(CE);
10051006
continue;
10061007
}
10071008

@@ -1047,9 +1048,8 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
10471048
// To further other optimizations, loop over all users of NewGV and try to
10481049
// constant prop them. This will promote GEP instructions with constant
10491050
// indices into GEP constant-exprs, which will allow global-opt to hack on it.
1050-
ConstantPropUsersOf(NewGV, DL, TLI);
1051-
if (RepValue != NewGV)
1052-
ConstantPropUsersOf(RepValue, DL, TLI);
1051+
for (auto *CE : RepValues)
1052+
ConstantPropUsersOf(CE, DL, TLI);
10531053

10541054
return NewGV;
10551055
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -globalopt -S < %s | FileCheck %s
3+
; RUN: opt -passes=globalopt -S < %s | FileCheck %s
4+
5+
@g = internal global i32* null, align 8
6+
7+
define signext i32 @f() local_unnamed_addr {
8+
; CHECK-LABEL: @f(
9+
; CHECK-NEXT: entry:
10+
; CHECK-NEXT: call void @f1()
11+
; CHECK-NEXT: store i32 1, i32* @g.body, align 4
12+
; CHECK-NEXT: call void @f1()
13+
; CHECK-NEXT: store i8 2, i8* bitcast (i32* @g.body to i8*), align 4
14+
; CHECK-NEXT: ret i32 1
15+
;
16+
entry:
17+
%call = call i8* @malloc(i64 4)
18+
%b = bitcast i8* %call to i32*
19+
store i32* %b, i32** @g, align 8
20+
call void @f1()
21+
%0 = load i32*, i32** @g, align 8
22+
store i32 1, i32* %0, align 4
23+
call void @f1()
24+
%1 = load i8*, i8** bitcast (i32** @g to i8**), align 8
25+
store i8 2, i8* %1, align 4
26+
ret i32 1
27+
}
28+
29+
define signext i32 @main() {
30+
; CHECK-LABEL: @main(
31+
; CHECK-NEXT: entry:
32+
; CHECK-NEXT: [[CALL:%.*]] = call signext i32 @f()
33+
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @g.body, align 4
34+
; CHECK-NEXT: ret i32 [[TMP0]]
35+
;
36+
entry:
37+
%call = call signext i32 @f()
38+
%0 = load i32*, i32** @g, align 8
39+
%1 = load i32, i32* %0, align 4
40+
ret i32 %1
41+
}
42+
43+
declare noalias align 16 i8* @malloc(i64)
44+
declare void @f1()

0 commit comments

Comments
 (0)