Skip to content

Commit 9f7567d

Browse files
authored
[PreISelIntrinsicLowering] Reuse previously generated GlobalVariable for memset_pattern16 when possible (#144677)
As Constants are already uniquified, we can use a map to keep track of whether a GlobalVariable was produced for a given Constant or not. Repeated globals with the same value was one of the codegen differences noted in #126736. This patch removes that diff, producing cleaner output.
1 parent ff8049a commit 9f7567d

File tree

2 files changed

+36
-30
lines changed

2 files changed

+36
-30
lines changed

llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ struct PreISelIntrinsicLowering {
6868

6969
static bool shouldExpandMemIntrinsicWithSize(Value *Size,
7070
const TargetTransformInfo &TTI);
71-
bool expandMemIntrinsicUses(Function &F) const;
71+
bool
72+
expandMemIntrinsicUses(Function &F,
73+
DenseMap<Constant *, GlobalVariable *> &CMap) const;
7274
bool lowerIntrinsics(Module &M) const;
7375
};
7476

@@ -295,7 +297,8 @@ static Constant *getMemSetPattern16Value(MemSetPatternInst *Inst,
295297

296298
// TODO: Handle atomic memcpy and memcpy.inline
297299
// TODO: Pass ScalarEvolution
298-
bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const {
300+
bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
301+
Function &F, DenseMap<Constant *, GlobalVariable *> &CMap) const {
299302
Intrinsic::ID ID = F.getIntrinsicID();
300303
bool Changed = false;
301304

@@ -411,13 +414,20 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const {
411414
// global.
412415
assert(Memset->getRawDest()->getType()->getPointerAddressSpace() == 0 &&
413416
"Should have skipped if non-zero AS");
414-
GlobalVariable *GV = new GlobalVariable(
415-
*M, PatternValue->getType(), /*isConstant=*/true,
416-
GlobalValue::PrivateLinkage, PatternValue, ".memset_pattern");
417-
GV->setUnnamedAddr(
418-
GlobalValue::UnnamedAddr::Global); // Ok to merge these.
419-
// TODO: Consider relaxing alignment requirement.
420-
GV->setAlignment(Align(16));
417+
GlobalVariable *GV;
418+
auto It = CMap.find(PatternValue);
419+
if (It != CMap.end()) {
420+
GV = It->second;
421+
} else {
422+
GV = new GlobalVariable(
423+
*M, PatternValue->getType(), /*isConstant=*/true,
424+
GlobalValue::PrivateLinkage, PatternValue, ".memset_pattern");
425+
GV->setUnnamedAddr(
426+
GlobalValue::UnnamedAddr::Global); // Ok to merge these.
427+
// TODO: Consider relaxing alignment requirement.
428+
GV->setAlignment(Align(16));
429+
CMap[PatternValue] = GV;
430+
}
421431
Value *PatternPtr = GV;
422432
Value *NumBytes = Builder.CreateMul(
423433
TLI.getAsSizeT(DL.getTypeAllocSize(Memset->getValue()->getType()),
@@ -446,6 +456,8 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const {
446456
}
447457

448458
bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
459+
// Map unique constants to globals.
460+
DenseMap<Constant *, GlobalVariable *> CMap;
449461
bool Changed = false;
450462
for (Function &F : M) {
451463
switch (F.getIntrinsicID()) {
@@ -457,7 +469,7 @@ bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
457469
case Intrinsic::memset:
458470
case Intrinsic::memset_inline:
459471
case Intrinsic::experimental_memset_pattern:
460-
Changed |= expandMemIntrinsicUses(F);
472+
Changed |= expandMemIntrinsicUses(F, CMap);
461473
break;
462474
case Intrinsic::load_relative:
463475
Changed |= lowerLoadRelative(F);

llvm/test/Transforms/PreISelIntrinsicLowering/X86/memset-pattern.ll

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,10 @@
44
;.
55
; CHECK: @G = global i32 5
66
; CHECK: @.memset_pattern = private unnamed_addr constant [2 x ptr] [ptr @G, ptr @G], align 16
7-
; CHECK: @.memset_pattern.1 = private unnamed_addr constant [2 x ptr] [ptr @G, ptr @G], align 16
8-
; CHECK: @.memset_pattern.2 = private unnamed_addr constant [2 x i64] [i64 -6148895925951734307, i64 -6148895925951734307], align 16
9-
; CHECK: @.memset_pattern.3 = private unnamed_addr constant [2 x i64] [i64 -6148895925951734307, i64 -6148895925951734307], align 16
10-
; CHECK: @.memset_pattern.4 = private unnamed_addr constant [2 x i64] [i64 -6148895925951734307, i64 -6148895925951734307], align 16
11-
; CHECK: @.memset_pattern.5 = private unnamed_addr constant [2 x i64] [i64 4614256656552045848, i64 4614256656552045848], align 16
12-
; CHECK: @.memset_pattern.6 = private unnamed_addr constant [8 x i16] [i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555], align 16
13-
; CHECK: @.memset_pattern.7 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16
14-
; CHECK: @.memset_pattern.8 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16
15-
; CHECK: @.memset_pattern.9 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16
16-
; CHECK: @.memset_pattern.10 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16
7+
; CHECK: @.memset_pattern.1 = private unnamed_addr constant [2 x i64] [i64 -6148895925951734307, i64 -6148895925951734307], align 16
8+
; CHECK: @.memset_pattern.2 = private unnamed_addr constant [2 x i64] [i64 4614256656552045848, i64 4614256656552045848], align 16
9+
; CHECK: @.memset_pattern.3 = private unnamed_addr constant [8 x i16] [i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555], align 16
10+
; CHECK: @.memset_pattern.4 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16
1711
;.
1812
define void @memset_pattern_i128_1_dynvalue(ptr %a, i128 %value) nounwind {
1913
; CHECK-LABEL: define void @memset_pattern_i128_1_dynvalue(
@@ -36,7 +30,7 @@ define void @memset_pattern_i128_1_dynvalue(ptr %a, i128 %value) nounwind {
3630
define void @memset_pattern_i128_1(ptr %a, i128 %value) nounwind {
3731
; CHECK-LABEL: define void @memset_pattern_i128_1(
3832
; CHECK-SAME: ptr [[A:%.*]], i128 [[VALUE:%.*]]) #[[ATTR0]] {
39-
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.7, i64 16)
33+
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.4, i64 16)
4034
; CHECK-NEXT: ret void
4135
;
4236
tail call void @llvm.experimental.memset.pattern(ptr %a, i128 u0xaaaaaaaabbbbbbbbccccccccdddddddd, i64 1, i1 false)
@@ -64,7 +58,7 @@ define void @memset_pattern_i128_1_nz_as(ptr addrspace(1) %a, i128 %value) nounw
6458
define void @memset_pattern_i128_1_align_attr(ptr align(16) %a, i128 %value) nounwind {
6559
; CHECK-LABEL: define void @memset_pattern_i128_1_align_attr(
6660
; CHECK-SAME: ptr align 16 [[A:%.*]], i128 [[VALUE:%.*]]) #[[ATTR0]] {
67-
; CHECK-NEXT: call void @memset_pattern16(ptr align 16 [[A]], ptr @.memset_pattern.8, i64 16)
61+
; CHECK-NEXT: call void @memset_pattern16(ptr align 16 [[A]], ptr @.memset_pattern.4, i64 16)
6862
; CHECK-NEXT: ret void
6963
;
7064
tail call void @llvm.experimental.memset.pattern(ptr align(16) %a, i128 u0xaaaaaaaabbbbbbbbccccccccdddddddd, i64 1, i1 false)
@@ -74,7 +68,7 @@ define void @memset_pattern_i128_1_align_attr(ptr align(16) %a, i128 %value) nou
7468
define void @memset_pattern_i128_16(ptr %a) nounwind {
7569
; CHECK-LABEL: define void @memset_pattern_i128_16(
7670
; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
77-
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.9, i64 256)
71+
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.4, i64 256)
7872
; CHECK-NEXT: ret void
7973
;
8074
tail call void @llvm.experimental.memset.pattern(ptr %a, i128 u0xaaaaaaaabbbbbbbbccccccccdddddddd, i64 16, i1 false)
@@ -85,7 +79,7 @@ define void @memset_pattern_i128_x(ptr %a, i64 %x) nounwind {
8579
; CHECK-LABEL: define void @memset_pattern_i128_x(
8680
; CHECK-SAME: ptr [[A:%.*]], i64 [[X:%.*]]) #[[ATTR0]] {
8781
; CHECK-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
88-
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.10, i64 [[TMP1]])
82+
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.4, i64 [[TMP1]])
8983
; CHECK-NEXT: ret void
9084
;
9185
tail call void @llvm.experimental.memset.pattern(ptr %a, i128 u0xaaaaaaaabbbbbbbbccccccccdddddddd, i64 %x, i1 false)
@@ -115,7 +109,7 @@ define void @memset_pattern_i16_x(ptr %a, i64 %x) nounwind {
115109
; CHECK-LABEL: define void @memset_pattern_i16_x(
116110
; CHECK-SAME: ptr [[A:%.*]], i64 [[X:%.*]]) #[[ATTR0]] {
117111
; CHECK-NEXT: [[TMP1:%.*]] = mul i64 2, [[X]]
118-
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.6, i64 [[TMP1]])
112+
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.3, i64 [[TMP1]])
119113
; CHECK-NEXT: ret void
120114
;
121115
tail call void @llvm.experimental.memset.pattern(ptr %a, i16 u0xabcd, i64 %x, i1 false)
@@ -126,7 +120,7 @@ define void @memset_pattern_i64_x(ptr %a, i64 %x) nounwind {
126120
; CHECK-LABEL: define void @memset_pattern_i64_x(
127121
; CHECK-SAME: ptr [[A:%.*]], i64 [[X:%.*]]) #[[ATTR0]] {
128122
; CHECK-NEXT: [[TMP1:%.*]] = mul i64 8, [[X]]
129-
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.4, i64 [[TMP1]])
123+
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.1, i64 [[TMP1]])
130124
; CHECK-NEXT: ret void
131125
;
132126
tail call void @llvm.experimental.memset.pattern(ptr %a, i64 u0xaaaabbbbccccdddd, i64 %x, i1 false)
@@ -137,7 +131,7 @@ define void @memset_pattern_i64_x(ptr %a, i64 %x) nounwind {
137131
define void @memset_pattern_i64_128_tbaa(ptr %a) nounwind {
138132
; CHECK-LABEL: define void @memset_pattern_i64_128_tbaa(
139133
; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
140-
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.5, i64 1024), !tbaa [[TBAA0:![0-9]+]]
134+
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.2, i64 1024), !tbaa [[TBAA0:![0-9]+]]
141135
; CHECK-NEXT: ret void
142136
;
143137
tail call void @llvm.experimental.memset.pattern(ptr %a, i64 u0x400921fb54442d18, i64 128, i1 false), !tbaa !5
@@ -154,7 +148,7 @@ define void @memset_pattern_i64_narrow_idx(ptr %a, i32 %x) nounwind {
154148
; CHECK-SAME: ptr [[A:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
155149
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[X]] to i64
156150
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 8, [[TMP1]]
157-
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.3, i64 [[TMP2]])
151+
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.1, i64 [[TMP2]])
158152
; CHECK-NEXT: ret void
159153
;
160154
tail call void @llvm.experimental.memset.pattern(ptr %a, i64 u0xaaaabbbbccccdddd, i32 %x, i1 false)
@@ -166,7 +160,7 @@ define void @memset_pattern_i64_wide_idx(ptr %a, i128 %x) nounwind {
166160
; CHECK-SAME: ptr [[A:%.*]], i128 [[X:%.*]]) #[[ATTR0]] {
167161
; CHECK-NEXT: [[TMP1:%.*]] = trunc i128 [[X]] to i64
168162
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 8, [[TMP1]]
169-
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.2, i64 [[TMP2]])
163+
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.1, i64 [[TMP2]])
170164
; CHECK-NEXT: ret void
171165
;
172166
tail call void @llvm.experimental.memset.pattern(ptr %a, i64 u0xaaaabbbbccccdddd, i128 %x, i1 false)
@@ -189,7 +183,7 @@ define void @memset_pattern_i64_x_fromptr(ptr %a, i64 %x) nounwind {
189183
; CHECK-LABEL: define void @memset_pattern_i64_x_fromptr(
190184
; CHECK-SAME: ptr [[A:%.*]], i64 [[X:%.*]]) #[[ATTR0]] {
191185
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 8, [[X]]
192-
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.1, i64 [[TMP2]])
186+
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern, i64 [[TMP2]])
193187
; CHECK-NEXT: ret void
194188
;
195189
tail call void @llvm.experimental.memset.pattern(ptr %a, ptr @G, i64 %x, i1 false)

0 commit comments

Comments
 (0)