From d6f19cdc0bda8e6d9ee89569fecc0b4a06b1fcc9 Mon Sep 17 00:00:00 2001 From: Alex Bradbury Date: Fri, 28 Feb 2025 13:03:43 +0000 Subject: [PATCH 1/3] [PreISelIntrinsicLowering] Zext/trunc count parameter as necessary for memset_pattern16 emission This patch cleans up the handling of the count parameter in general, though was initially motivated by a compiler crash upon a memset.pattern with a narrow count causing a compiler crash due to different types for CreateMul when converting the count to the number of bytes. The logic used to name globals means there is some minor renaming churn in the output to test/Transforms/PreISelIntrinsicLowering/X86/memset-pattern.ll irrelevant to the newly added tests (that would crash before). --- llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | 16 ++++--- .../X86/memset-pattern.ll | 48 ++++++++++++++----- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp index 27fa0b43d74f6..bc4496a167375 100644 --- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp +++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp @@ -394,11 +394,12 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const { Module *M = Memset->getModule(); const DataLayout &DL = Memset->getDataLayout(); + Type *DestPtrTy = Memset->getRawDest()->getType(); + Type *IntIdxTy = DL.getIndexType(DestPtrTy); StringRef FuncName = "memset_pattern16"; - FunctionCallee MSP = getOrInsertLibFunc( - M, TLI, LibFunc_memset_pattern16, Builder.getVoidTy(), - Memset->getRawDest()->getType(), Builder.getPtrTy(), - Memset->getLength()->getType()); + FunctionCallee MSP = getOrInsertLibFunc(M, TLI, LibFunc_memset_pattern16, + Builder.getVoidTy(), DestPtrTy, + Builder.getPtrTy(), IntIdxTy); inferNonMandatoryLibFuncAttrs(M, FuncName, TLI); // Otherwise we should form a memset_pattern16. PatternValue is known @@ -415,9 +416,10 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const { GV->setAlignment(Align(16)); Value *PatternPtr = GV; Value *NumBytes = Builder.CreateMul( - Builder.getInt64(DL.getTypeSizeInBits(Memset->getValue()->getType()) / - 8), - Memset->getLength()); + ConstantInt::get(IntIdxTy, + DL.getTypeSizeInBits(Memset->getValue()->getType()) / + 8), + Builder.CreateZExtOrTrunc(Memset->getLength(), IntIdxTy)); CallInst *MemsetPattern16Call = Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes}); MemsetPattern16Call->setAAMetadata(Memset->getAAMetadata()); diff --git a/llvm/test/Transforms/PreISelIntrinsicLowering/X86/memset-pattern.ll b/llvm/test/Transforms/PreISelIntrinsicLowering/X86/memset-pattern.ll index 7cfdcb8578809..c52213d9a951d 100644 --- a/llvm/test/Transforms/PreISelIntrinsicLowering/X86/memset-pattern.ll +++ b/llvm/test/Transforms/PreISelIntrinsicLowering/X86/memset-pattern.ll @@ -3,12 +3,14 @@ ;. ; CHECK: @.memset_pattern = private unnamed_addr constant [2 x i64] [i64 -6148895925951734307, i64 -6148895925951734307], align 16 -; CHECK: @.memset_pattern.1 = private unnamed_addr constant [2 x i64] [i64 4614256656552045848, i64 4614256656552045848], align 16 -; CHECK: @.memset_pattern.2 = 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 -; CHECK: @.memset_pattern.3 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16 -; CHECK: @.memset_pattern.4 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16 +; CHECK: @.memset_pattern.1 = private unnamed_addr constant [2 x i64] [i64 -6148895925951734307, i64 -6148895925951734307], align 16 +; CHECK: @.memset_pattern.2 = private unnamed_addr constant [2 x i64] [i64 -6148895925951734307, i64 -6148895925951734307], align 16 +; CHECK: @.memset_pattern.3 = private unnamed_addr constant [2 x i64] [i64 4614256656552045848, i64 4614256656552045848], align 16 +; CHECK: @.memset_pattern.4 = 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 ; CHECK: @.memset_pattern.5 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16 ; CHECK: @.memset_pattern.6 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16 +; CHECK: @.memset_pattern.7 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16 +; CHECK: @.memset_pattern.8 = private unnamed_addr constant i128 -113427455635030943652277463699152839203, align 16 ;. define void @memset_pattern_i128_1_dynvalue(ptr %a, i128 %value) nounwind { ; CHECK-LABEL: define void @memset_pattern_i128_1_dynvalue( @@ -31,7 +33,7 @@ define void @memset_pattern_i128_1_dynvalue(ptr %a, i128 %value) nounwind { define void @memset_pattern_i128_1(ptr %a, i128 %value) nounwind { ; CHECK-LABEL: define void @memset_pattern_i128_1( ; CHECK-SAME: ptr [[A:%.*]], i128 [[VALUE:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.3, i64 16) +; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.5, i64 16) ; CHECK-NEXT: ret void ; tail call void @llvm.experimental.memset.pattern(ptr %a, i128 u0xaaaaaaaabbbbbbbbccccccccdddddddd, i64 1, i1 false) @@ -59,7 +61,7 @@ define void @memset_pattern_i128_1_nz_as(ptr addrspace(1) %a, i128 %value) nounw define void @memset_pattern_i128_1_align_attr(ptr align(16) %a, i128 %value) nounwind { ; CHECK-LABEL: define void @memset_pattern_i128_1_align_attr( ; CHECK-SAME: ptr align 16 [[A:%.*]], i128 [[VALUE:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: call void @memset_pattern16(ptr align 16 [[A]], ptr @.memset_pattern.4, i64 16) +; CHECK-NEXT: call void @memset_pattern16(ptr align 16 [[A]], ptr @.memset_pattern.6, i64 16) ; CHECK-NEXT: ret void ; tail call void @llvm.experimental.memset.pattern(ptr align(16) %a, i128 u0xaaaaaaaabbbbbbbbccccccccdddddddd, i64 1, i1 false) @@ -69,7 +71,7 @@ define void @memset_pattern_i128_1_align_attr(ptr align(16) %a, i128 %value) nou define void @memset_pattern_i128_16(ptr %a) nounwind { ; CHECK-LABEL: define void @memset_pattern_i128_16( ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.5, i64 256) +; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.7, i64 256) ; CHECK-NEXT: ret void ; tail call void @llvm.experimental.memset.pattern(ptr %a, i128 u0xaaaaaaaabbbbbbbbccccccccdddddddd, i64 16, i1 false) @@ -80,7 +82,7 @@ define void @memset_pattern_i128_x(ptr %a, i64 %x) nounwind { ; CHECK-LABEL: define void @memset_pattern_i128_x( ; CHECK-SAME: ptr [[A:%.*]], i64 [[X:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] -; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.6, i64 [[TMP1]]) +; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.8, i64 [[TMP1]]) ; CHECK-NEXT: ret void ; tail call void @llvm.experimental.memset.pattern(ptr %a, i128 u0xaaaaaaaabbbbbbbbccccccccdddddddd, i64 %x, i1 false) @@ -110,7 +112,7 @@ define void @memset_pattern_i16_x(ptr %a, i64 %x) nounwind { ; CHECK-LABEL: define void @memset_pattern_i16_x( ; CHECK-SAME: ptr [[A:%.*]], i64 [[X:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[TMP1:%.*]] = mul i64 2, [[X]] -; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.2, i64 [[TMP1]]) +; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.4, i64 [[TMP1]]) ; CHECK-NEXT: ret void ; tail call void @llvm.experimental.memset.pattern(ptr %a, i16 u0xabcd, i64 %x, i1 false) @@ -121,7 +123,7 @@ define void @memset_pattern_i64_x(ptr %a, i64 %x) nounwind { ; CHECK-LABEL: define void @memset_pattern_i64_x( ; CHECK-SAME: ptr [[A:%.*]], i64 [[X:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[TMP1:%.*]] = mul i64 8, [[X]] -; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern, i64 [[TMP1]]) +; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.2, i64 [[TMP1]]) ; CHECK-NEXT: ret void ; tail call void @llvm.experimental.memset.pattern(ptr %a, i64 u0xaaaabbbbccccdddd, i64 %x, i1 false) @@ -132,13 +134,37 @@ define void @memset_pattern_i64_x(ptr %a, i64 %x) nounwind { define void @memset_pattern_i64_128_tbaa(ptr %a) nounwind { ; CHECK-LABEL: define void @memset_pattern_i64_128_tbaa( ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.1, i64 1024), !tbaa [[TBAA0:![0-9]+]] +; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.3, i64 1024), !tbaa [[TBAA0:![0-9]+]] ; CHECK-NEXT: ret void ; tail call void @llvm.experimental.memset.pattern(ptr %a, i64 u0x400921fb54442d18, i64 128, i1 false), !tbaa !5 ret void } +define void @memset_pattern_i64_narrow_idx(ptr %a, i32 %x) nounwind { +; CHECK-LABEL: define void @memset_pattern_i64_narrow_idx( +; CHECK-SAME: ptr [[A:%.*]], i32 [[X:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[X]] to i64 +; CHECK-NEXT: [[TMP2:%.*]] = mul i64 8, [[TMP1]] +; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern.1, i64 [[TMP2]]) +; CHECK-NEXT: ret void +; + tail call void @llvm.experimental.memset.pattern(ptr %a, i64 u0xaaaabbbbccccdddd, i32 %x, i1 false) + ret void +} + +define void @memset_pattern_i64_wide_idx(ptr %a, i128 %x) nounwind { +; CHECK-LABEL: define void @memset_pattern_i64_wide_idx( +; CHECK-SAME: ptr [[A:%.*]], i128 [[X:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP1:%.*]] = trunc i128 [[X]] to i64 +; CHECK-NEXT: [[TMP2:%.*]] = mul i64 8, [[TMP1]] +; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr @.memset_pattern, i64 [[TMP2]]) +; CHECK-NEXT: ret void +; + tail call void @llvm.experimental.memset.pattern(ptr %a, i64 u0xaaaabbbbccccdddd, i128 %x, i1 false) + ret void +} + !5 = !{!6, !6, i64 0} !6 = !{!"double", !7, i64 0} !7 = !{!"omnipotent char", !8, i64 0} From 1de9cefae45602cfa314a9782c1d717a890ed665 Mon Sep 17 00:00:00 2001 From: Alex Bradbury Date: Wed, 19 Mar 2025 11:07:22 +0000 Subject: [PATCH 2/3] Use TLI.getSizeTType and TLI.getAsSizeT helpers --- llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp index 63a6255de276d..85c82812fa49a 100644 --- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp +++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp @@ -395,7 +395,7 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const { const DataLayout &DL = Memset->getDataLayout(); Type *DestPtrTy = Memset->getRawDest()->getType(); - Type *IntIdxTy = DL.getIndexType(DestPtrTy); + Type *IntIdxTy = TLI.getSizeTType(*M); StringRef FuncName = "memset_pattern16"; FunctionCallee MSP = getOrInsertLibFunc(M, TLI, LibFunc_memset_pattern16, Builder.getVoidTy(), DestPtrTy, @@ -416,8 +416,8 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const { GV->setAlignment(Align(16)); Value *PatternPtr = GV; Value *NumBytes = Builder.CreateMul( - ConstantInt::get(IntIdxTy, - DL.getTypeAllocSize(Memset->getValue()->getType())), + TLI.getAsSizeT(DL.getTypeAllocSize(Memset->getValue()->getType()), + *M), Builder.CreateZExtOrTrunc(Memset->getLength(), IntIdxTy)); CallInst *MemsetPattern16Call = Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes}); From 7f92827a3e00cc2765cefcb691ebc1ebf5a3f1b9 Mon Sep 17 00:00:00 2001 From: Alex Bradbury Date: Wed, 19 Mar 2025 11:15:21 +0000 Subject: [PATCH 3/3] IntIdxTy -> SizeTTy --- llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp index 85c82812fa49a..9dc1764b49e46 100644 --- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp +++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp @@ -395,11 +395,11 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const { const DataLayout &DL = Memset->getDataLayout(); Type *DestPtrTy = Memset->getRawDest()->getType(); - Type *IntIdxTy = TLI.getSizeTType(*M); + Type *SizeTTy = TLI.getSizeTType(*M); StringRef FuncName = "memset_pattern16"; FunctionCallee MSP = getOrInsertLibFunc(M, TLI, LibFunc_memset_pattern16, Builder.getVoidTy(), DestPtrTy, - Builder.getPtrTy(), IntIdxTy); + Builder.getPtrTy(), SizeTTy); inferNonMandatoryLibFuncAttrs(M, FuncName, TLI); // Otherwise we should form a memset_pattern16. PatternValue is known @@ -418,7 +418,7 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const { Value *NumBytes = Builder.CreateMul( TLI.getAsSizeT(DL.getTypeAllocSize(Memset->getValue()->getType()), *M), - Builder.CreateZExtOrTrunc(Memset->getLength(), IntIdxTy)); + Builder.CreateZExtOrTrunc(Memset->getLength(), SizeTTy)); CallInst *MemsetPattern16Call = Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes}); MemsetPattern16Call->setAAMetadata(Memset->getAAMetadata());