[MemCpyOpt][profcheck] Set unknown branch weights for certain selects (#167597)

Issue #147390
This commit is contained in:
Mircea Trofin
2025-11-14 10:36:50 -08:00
committed by GitHub
parent 44b94a4f75
commit 17789e9fa8
2 changed files with 10 additions and 3 deletions

View File

@@ -47,6 +47,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ProfDataUtils.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
@@ -1366,6 +1367,10 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
Value *SizeDiff = Builder.CreateSub(DestSize, SrcSize);
Value *MemsetLen = Builder.CreateSelect(
Ule, ConstantInt::getNullValue(DestSize->getType()), SizeDiff);
// FIXME (#167968): we could explore estimating the branch_weights based on
// value profiling data about the 2 sizes.
if (auto *SI = dyn_cast<SelectInst>(MemsetLen))
setExplicitlyUnknownBranchWeightsIfProfiled(*SI, DEBUG_TYPE);
Instruction *NewMemSet =
Builder.CreateMemSet(Builder.CreatePtrAdd(Dest, SrcSize),
MemSet->getOperand(1), MemsetLen, Alignment);

View File

@@ -7,14 +7,14 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1)
define void @test_constant(i64 %src_size, ptr %dst, i64 %dst_size, i8 %c) !dbg !5 {
define void @test_constant(i64 %src_size, ptr %dst, i64 %dst_size, i8 %c) !dbg !5 !prof !14 {
; CHECK-LABEL: define void @test_constant(
; CHECK-SAME: i64 [[SRC_SIZE:%.*]], ptr [[DST:%.*]], i64 [[DST_SIZE:%.*]], i8 [[C:%.*]]) !dbg [[DBG5:![0-9]+]] {
; CHECK-SAME: i64 [[SRC_SIZE:%.*]], ptr [[DST:%.*]], i64 [[DST_SIZE:%.*]], i8 [[C:%.*]]) !dbg [[DBG5:![0-9]+]] !prof {{.*}} {
; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])
; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE]], [[SRC_SIZE]], !dbg [[DBG11:![0-9]+]]
; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], [[SRC_SIZE]], !dbg [[DBG11]]
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]], !dbg [[DBG11]]
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]], !dbg [[DBG11]], !prof [[SELPROF:![0-9]+]]
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[DST]], i64 [[SRC_SIZE]], !dbg [[DBG11]]
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP4]], i8 [[C]], i64 [[TMP3]], i1 false), !dbg [[DBG11]]
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr @C, i64 [[SRC_SIZE]], i1 false), !dbg [[DBG12:![0-9]+]]
@@ -29,6 +29,7 @@ define void @test_constant(i64 %src_size, ptr %dst, i64 %dst_size, i8 %c) !dbg !
; Validate that the memset is mapped to DILocation for the original memset.
; CHECK: [[DBG11]] = !DILocation(line: 1,
; CHECK: [[SELPROF]] = !{!"unknown", !"memcpyopt"}
; CHECK: [[DBG12]] = !DILocation(line: 2,
; CHECK: [[DBG13]] = !DILocation(line: 3,
@@ -50,3 +51,4 @@ define void @test_constant(i64 %src_size, ptr %dst, i64 %dst_size, i8 %c) !dbg !
!11 = !DILocation(line: 1, column: 1, scope: !5)
!12 = !DILocation(line: 2, column: 1, scope: !5)
!13 = !DILocation(line: 3, column: 1, scope: !5)
!14 = !{!"function_entry_count", i32 10}