; LLVM IR from huawei-noah/bolt :: compute/tensor/src/cpu/x86/int8/avx512 (quantize)

; Unoptimized IR (clang -disable-llvm-passes):
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.TensorDesc = type { i32, i32, i32, [20 x i32] }

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #0

; Function Attrs: inlinehint mustprogress nounwind uwtable
declare dso_local noundef i32 @_Z17tensorNumElements10TensorDesc(ptr noundef byval(%struct.TensorDesc) align 8) #1

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #2

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #0

; Function Attrs: mustprogress uwtable
define dso_local noundef i32 @_Z15transformU8ToI810TensorDescPKhPS_Pa(ptr noundef byval(%struct.TensorDesc) align 8 %0, ptr noundef %1, ptr noundef %2, ptr noundef %3) #3 {
  %5 = alloca ptr, align 8
  %6 = alloca ptr, align 8
  %7 = alloca ptr, align 8
  %8 = alloca i32, align 4
  %9 = alloca %struct.TensorDesc, align 8
  %10 = alloca i32, align 4
  %11 = alloca i64, align 8
  store ptr %1, ptr %5, align 8, !tbaa !5
  store ptr %2, ptr %6, align 8, !tbaa !5
  store ptr %3, ptr %7, align 8, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 4, ptr %8) #4
  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %9, ptr align 8 %0, i64 92, i1 false), !tbaa.struct !9
  %12 = call noundef i32 @_Z17tensorNumElements10TensorDesc(ptr noundef byval(%struct.TensorDesc) align 8 %9)
  store i32 %12, ptr %8, align 4, !tbaa !14
  call void @llvm.lifetime.start.p0(i64 4, ptr %10) #4
  %13 = load i32, ptr %8, align 4, !tbaa !14
  %14 = udiv i32 %13, 64
  store i32 %14, ptr %10, align 4, !tbaa !14
  call void @llvm.lifetime.start.p0(i64 8, ptr %11) #4
  %15 = load i32, ptr %8, align 4, !tbaa !14
  %16 = urem i32 %15, 64
  %17 = zext i32 %16 to i64
  store i64 %17, ptr %11, align 8, !tbaa !17
  %18 = load i64, ptr %11, align 8, !tbaa !17
  %19 = icmp eq i64 %18, 63
  br i1 %19, label %20, label %21

20:                                               ; preds = %4
  store i64 -1, ptr %11, align 8, !tbaa !17
  br label %25

21:                                               ; preds = %4
  %22 = load i64, ptr %11, align 8, !tbaa !17
  %23 = shl i64 1, %22
  %24 = sub nsw i64 %23, 1
  store i64 %24, ptr %11, align 8, !tbaa !17
  br label %25

25:                                               ; preds = %21, %20
  %26 = load ptr, ptr %5, align 8, !tbaa !5
  %27 = load ptr, ptr %7, align 8, !tbaa !5
  %28 = load i32, ptr %10, align 4, !tbaa !14
  %29 = load i64, ptr %11, align 8, !tbaa !17
  %30 = call { ptr, ptr } asm sideeffect "mov $$0x80, %ebx \0A\09vmovd %ebx, %xmm1                    \0A\09vpbroadcastb %xmm1, %zmm2            \0A\09mov $2, %ebx \0A\09cmp $$0x0, %ebx                         \0A\09je 1f                                    \0A\09.align 16                             \0A\090:                                    \0A\09vpaddb ($0), %zmm2, %zmm0              \0A\09vmovups %zmm0, ($1)              \0A\09add $$0x40, $0                         \0A\09add $$0x40, $1                         \0A\09dec %ebx                             \0A\09jg 0b                                 \0A\09.align 16                             \0A\091:                                    \0A\09cmp $$0x0, %rax                       \0A\09je 2f                                 \0A\09kmovq %rax, %k1                     \0A\09vxorps %zmm0, %zmm0, %zmm0         \0A\09vxorps %zmm1, %zmm1, %zmm1         \0A\09vmovdqu8 ($0), %zmm1 {%k1}  \0A\09vpaddb %zmm1, %zmm2, %zmm0 {%k1}   \0A\09vmovdqu8 %zmm0, ($1) {%k1}              \0A\09.align 16                             \0A\092:                                    \0A\09", "=r,=r,r,{ax},0,1,~{k1},~{ebx},~{zmm0},~{zmm1},~{zmm2},~{memory},~{cc},~{dirflag},~{fpsr},~{flags}"(i32 %28, i64 %29, ptr %26, ptr %27) #4, !srcloc !19
  %31 = extractvalue { ptr, ptr } %30, 0
  %32 = extractvalue { ptr, ptr } %30, 1
  store ptr %31, ptr %5, align 8, !tbaa !5
  store ptr %32, ptr %7, align 8, !tbaa !5
  call void @llvm.lifetime.end.p0(i64 8, ptr %11) #4
  call void @llvm.lifetime.end.p0(i64 4, ptr %10) #4
  call void @llvm.lifetime.end.p0(i64 4, ptr %8) #4
  ret i32 0
}

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #1 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #3 = { mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #4 = { nounwind }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 19.1.0 (git@github.com:llvm/llvm-project.git a4bf6cd7cfb1a1421ba92bca9d017b49936c55e4)"}
!5 = !{!6, !6, i64 0}
!6 = !{!"any pointer", !7, i64 0}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C++ TBAA"}
!9 = !{i64 0, i64 4, !10, i64 4, i64 4, !12, i64 8, i64 4, !14, i64 12, i64 80, !16}
!10 = !{!11, !11, i64 0}
!11 = !{!"_ZTS8DataType", !7, i64 0}
!12 = !{!13, !13, i64 0}
!13 = !{!"_ZTS10DataFormat", !7, i64 0}
!14 = !{!15, !15, i64 0}
!15 = !{!"int", !7, i64 0}
!16 = !{!7, !7, i64 0}
!17 = !{!18, !18, i64 0}
!18 = !{!"long", !7, i64 0}
!19 = !{i64 13616, i64 13636, i64 13708, i64 13780, i64 13827, i64 13900, i64 13974, i64 14045, i64 14116, i64 14190, i64 14257, i64 14328, i64 14399, i64 14470, i64 14541, i64 14614, i64 14685, i64 14756, i64 14827, i64 14898, i64 14969, i64 15040, i64 15105, i64 15179, i64 15256, i64 15327, i64 15398}


; Optimized IR (opt -passes='default<O3>'):
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.TensorDesc = type { i32, i32, i32, [20 x i32] }

; Function Attrs: inlinehint mustprogress nounwind uwtable
declare dso_local noundef i32 @_Z17tensorNumElements10TensorDesc(ptr noundef byval(%struct.TensorDesc) align 8) local_unnamed_addr #0

; Function Attrs: mustprogress uwtable
define dso_local noundef i32 @_Z15transformU8ToI810TensorDescPKhPS_Pa(ptr nocapture noundef readonly byval(%struct.TensorDesc) align 8 %0, ptr noundef %1, ptr nocapture noundef readnone %2, ptr noundef %3) local_unnamed_addr #1 {
  %5 = tail call noundef i32 @_Z17tensorNumElements10TensorDesc(ptr noundef nonnull byval(%struct.TensorDesc) align 8 %0)
  %6 = and i32 %5, 63
  %7 = icmp eq i32 %6, 63
  %8 = zext nneg i32 %6 to i64
  %notmask = shl nsw i64 -1, %8
  %9 = xor i64 %notmask, -1
  %.0 = select i1 %7, i64 -1, i64 %9
  %10 = lshr i32 %5, 6
  %11 = tail call { ptr, ptr } asm sideeffect "mov $$0x80, %ebx \0A\09vmovd %ebx, %xmm1                    \0A\09vpbroadcastb %xmm1, %zmm2            \0A\09mov $2, %ebx \0A\09cmp $$0x0, %ebx                         \0A\09je 1f                                    \0A\09.align 16                             \0A\090:                                    \0A\09vpaddb ($0), %zmm2, %zmm0              \0A\09vmovups %zmm0, ($1)              \0A\09add $$0x40, $0                         \0A\09add $$0x40, $1                         \0A\09dec %ebx                             \0A\09jg 0b                                 \0A\09.align 16                             \0A\091:                                    \0A\09cmp $$0x0, %rax                       \0A\09je 2f                                 \0A\09kmovq %rax, %k1                     \0A\09vxorps %zmm0, %zmm0, %zmm0         \0A\09vxorps %zmm1, %zmm1, %zmm1         \0A\09vmovdqu8 ($0), %zmm1 {%k1}  \0A\09vpaddb %zmm1, %zmm2, %zmm0 {%k1}   \0A\09vmovdqu8 %zmm0, ($1) {%k1}              \0A\09.align 16                             \0A\092:                                    \0A\09", "=r,=r,r,{ax},0,1,~{k1},~{ebx},~{zmm0},~{zmm1},~{zmm2},~{memory},~{cc},~{dirflag},~{fpsr},~{flags}"(i32 %10, i64 %.0, ptr %1, ptr %3) #2, !srcloc !5
  ret i32 0
}

attributes #0 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #2 = { nounwind }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 19.1.0 (git@github.com:llvm/llvm-project.git a4bf6cd7cfb1a1421ba92bca9d017b49936c55e4)"}
!5 = !{i64 13616, i64 13636, i64 13708, i64 13780, i64 13827, i64 13900, i64 13974, i64 14045, i64 14116, i64 14190, i64 14257, i64 14328, i64 14399, i64 14470, i64 14541, i64 14614, i64 14685, i64 14756, i64 14827, i64 14898, i64 14969, i64 15040, i64 15105, i64 15179, i64 15256, i64 15327, i64 15398}


; Effective O3 passes: DSEPass,EarlyCSEPass,GlobalOptPass,IPSCCPPass,InferFunctionAttrsPass,InstCombinePass,MemCpyOptPass,PostOrderFunctionAttrsPass,SROAPass,SimplifyCFGPass,TailCallElimPass