blob: 3fe30c95a2e6424b7f5e7095bb33cb56f6d0d49e [file]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc -mtriple=wasm32 -mattr=simd128 %s -o - | FileCheck %s
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
%struct.quantized_block_q8_0 = type { i16, [32 x i8] }
%struct.quantized_block_q4_0 = type { i16, [16 x i8] }
%struct.quantized_block_q2k = type { [16 x i8], [64 x i8], i16, i16 }
%struct.quantized_block_q8k = type { float, [256 x i8], [16 x i16] }
%struct.quantized_block_q4k = type { i16, i16, [12 x i8], [128 x i8] }
%struct.quantized_block_q4_1 = type { i16, i16, [16 x i8] }
%struct.quantized_block_q8_1 = type { i16, i16, [32 x i8] }
%struct.quantized_block_q5k = type { i16, i16, [12 x i8], [32 x i8], [128 x i8] }
%struct.quantized_block_q6k = type { [128 x i8], [64 x i8], [16 x i8], i16 }
define hidden float @vec_dot_q4_0_q8_0(i32 noundef %arg, ptr noundef readonly %arg1, ptr noundef readonly %arg2) {
; CHECK-LABEL: vec_dot_q4_0_q8_0:
; CHECK: .functype vec_dot_q4_0_q8_0 (i32, i32, i32) -> (f32)
; CHECK-NEXT: .local v128, v128
; CHECK-NEXT: # %bb.0: # %bb
; CHECK-NEXT: local.get 1
; CHECK-NEXT: v128.load32_zero 2:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_u
; CHECK-NEXT: i32x4.extend_low_i16x8_u
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: v128.const 15, 15, 15, 15
; CHECK-NEXT: v128.and
; CHECK-NEXT: v128.const -8, -8, -8, -8
; CHECK-NEXT: local.tee 4
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.get 2
; CHECK-NEXT: v128.load32_zero 2:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_s
; CHECK-NEXT: i32x4.extend_low_i16x8_s
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32x4.shr_u
; CHECK-NEXT: local.get 4
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.get 2
; CHECK-NEXT: v128.load32_zero 18:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_s
; CHECK-NEXT: i32x4.extend_low_i16x8_s
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i8x16.shuffle 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: f32.convert_i32_s
; CHECK-NEXT: # fallthrough-return
bb:
%i = lshr i32 %arg, 5
%i3 = icmp eq i32 %i, 0
br label %bb4
bb4: ; preds = %bb
%i5 = getelementptr inbounds %struct.quantized_block_q8_0, ptr %arg2, i32 0
%i6 = getelementptr inbounds i8, ptr %i5, i32 2
%i7 = getelementptr inbounds %struct.quantized_block_q4_0, ptr %arg1, i32 0
%i8 = getelementptr inbounds i8, ptr %i7, i32 2
%i9 = load <4 x i8>, ptr %i8, align 1
%i10 = zext <4 x i8> %i9 to <4 x i32>
%i11 = and <4 x i32> %i10, splat (i32 15)
%i12 = add nsw <4 x i32> %i11, splat (i32 -8)
%i13 = lshr <4 x i32> %i10, splat (i32 4)
%i14 = add nsw <4 x i32> %i13, splat (i32 -8)
%i15 = load <4 x i8>, ptr %i6, align 1
%i16 = sext <4 x i8> %i15 to <4 x i32>
%i17 = mul nsw <4 x i32> %i12, %i16
%i18 = getelementptr inbounds i8, ptr %i5, i32 18
%i19 = load <4 x i8>, ptr %i18, align 1
%i20 = sext <4 x i8> %i19 to <4 x i32>
%i21 = mul nsw <4 x i32> %i14, %i20
%i22 = add nsw <4 x i32> %i17, %i21
%i23 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %i22)
%result = sitofp i32 %i23 to float
ret float %result
}
; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)
declare float @llvm.fmuladd.f32(float, float, float) #0
define hidden float @vec_dot_q2k_q8k(i32 noundef %arg, ptr noundef readonly %arg1, ptr noundef readonly %arg2) {
; CHECK-LABEL: vec_dot_q2k_q8k:
; CHECK: .functype vec_dot_q2k_q8k (i32, i32, i32) -> (f32)
; CHECK-NEXT: .local i32, v128, v128, i32, v128, v128, v128
; CHECK-NEXT: # %bb.0: # %bb
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.set 2
; CHECK-NEXT: v128.const 0, 1, 2, 3
; CHECK-NEXT: local.set 4
; CHECK-NEXT: v128.const 0, 0, 0, 0
; CHECK-NEXT: local.set 5
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.set 6
; CHECK-NEXT: .LBB1_1: # %bb9
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: loop # label0:
; CHECK-NEXT: local.get 2
; CHECK-NEXT: local.get 4
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32x4.shr_u
; CHECK-NEXT: v128.const 32, 32, 32, 32
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.tee 7
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 4
; CHECK-NEXT: v128.const 31, 31, 31, 31
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.tee 8
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 2
; CHECK-NEXT: local.get 7
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 8
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 2
; CHECK-NEXT: local.get 7
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 8
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 2
; CHECK-NEXT: local.get 7
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 8
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load8_splat 0
; CHECK-NEXT: v128.load8_lane 0, 1
; CHECK-NEXT: v128.load8_lane 0, 2
; CHECK-NEXT: v128.load8_lane 0, 3
; CHECK-NEXT: i16x8.extend_low_i8x16_u
; CHECK-NEXT: i32x4.extend_low_i16x8_u
; CHECK-NEXT: local.tee 7
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: local.get 4
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32x4.shr_u
; CHECK-NEXT: local.tee 9
; CHECK-NEXT: v128.const 6, 6, 6, 6
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.tee 8
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.splat
; CHECK-NEXT: local.get 7
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: local.get 8
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.replace_lane 1
; CHECK-NEXT: local.get 7
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: local.get 8
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.replace_lane 2
; CHECK-NEXT: local.get 7
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: local.get 8
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.replace_lane 3
; CHECK-NEXT: v128.const 3, 3, 3, 3
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.add
; CHECK-NEXT: i32.load8_u 0
; CHECK-NEXT: i32.const 15
; CHECK-NEXT: i32.and
; CHECK-NEXT: i8x16.splat
; CHECK-NEXT: i16x8.extend_low_i8x16_u
; CHECK-NEXT: i32x4.extend_low_i16x8_u
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 6
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_zero 0:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_s
; CHECK-NEXT: i32x4.extend_low_i16x8_s
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: local.get 5
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.set 5
; CHECK-NEXT: local.get 4
; CHECK-NEXT: v128.const 4, 4, 4, 4
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.set 4
; CHECK-NEXT: local.get 6
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.tee 6
; CHECK-NEXT: i32.const 256
; CHECK-NEXT: i32.ne
; CHECK-NEXT: br_if 0 # 0: up to label0
; CHECK-NEXT: # %bb.2: # %bb61
; CHECK-NEXT: end_loop
; CHECK-NEXT: local.get 5
; CHECK-NEXT: local.get 5
; CHECK-NEXT: local.get 4
; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.tee 4
; CHECK-NEXT: local.get 4
; CHECK-NEXT: local.get 4
; CHECK-NEXT: i8x16.shuffle 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: f32.convert_i32_s
; CHECK-NEXT: # fallthrough-return
bb:
%i = lshr i32 %arg, 8
%i3 = icmp eq i32 %i, 0
br label %bb4
bb4: ; preds = %bb
%i5 = getelementptr inbounds %struct.quantized_block_q2k, ptr %arg1, i32 0
%i6 = getelementptr inbounds i8, ptr %i5, i32 16
%i7 = getelementptr inbounds %struct.quantized_block_q8k, ptr %arg2, i32 0
%i8 = getelementptr inbounds i8, ptr %i7, i32 4
br label %bb9
bb9: ; preds = %bb9, %bb4
%i10 = phi i32 [ 0, %bb4 ], [ %i58, %bb9 ]
%i11 = phi <4 x i32> [ zeroinitializer, %bb4 ], [ %i57, %bb9 ]
%i12 = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, %bb4 ], [ %i59, %bb9 ]
%i13 = lshr <4 x i32> %i12, splat (i32 4)
%i14 = extractelement <4 x i32> %i13, i64 0
%i15 = lshr <4 x i32> %i12, splat (i32 2)
%i16 = and <4 x i32> %i15, splat (i32 32)
%i17 = extractelement <4 x i32> %i16, i64 0
%i18 = extractelement <4 x i32> %i16, i64 1
%i19 = extractelement <4 x i32> %i16, i64 2
%i20 = extractelement <4 x i32> %i16, i64 3
%i21 = and <4 x i32> %i12, splat (i32 31)
%i22 = extractelement <4 x i32> %i21, i64 0
%i23 = extractelement <4 x i32> %i21, i64 1
%i24 = extractelement <4 x i32> %i21, i64 2
%i25 = extractelement <4 x i32> %i21, i64 3
%i26 = and <4 x i32> %i13, splat (i32 6)
%i27 = getelementptr inbounds i8, ptr %i6, i32 %i17
%i28 = getelementptr inbounds i8, ptr %i6, i32 %i18
%i29 = getelementptr inbounds i8, ptr %i6, i32 %i19
%i30 = getelementptr inbounds i8, ptr %i6, i32 %i20
%i31 = getelementptr inbounds i8, ptr %i27, i32 %i22
%i32 = getelementptr inbounds i8, ptr %i28, i32 %i23
%i33 = getelementptr inbounds i8, ptr %i29, i32 %i24
%i34 = getelementptr inbounds i8, ptr %i30, i32 %i25
%i35 = load i8, ptr %i31, align 1
%i36 = load i8, ptr %i32, align 1
%i37 = load i8, ptr %i33, align 1
%i38 = load i8, ptr %i34, align 1
%i39 = insertelement <4 x i8> poison, i8 %i35, i64 0
%i40 = insertelement <4 x i8> %i39, i8 %i36, i64 1
%i41 = insertelement <4 x i8> %i40, i8 %i37, i64 2
%i42 = insertelement <4 x i8> %i41, i8 %i38, i64 3
%i43 = zext <4 x i8> %i42 to <4 x i32>
%i44 = lshr <4 x i32> %i43, %i26
%i45 = and <4 x i32> %i44, splat (i32 3)
%i46 = getelementptr inbounds i8, ptr %i5, i32 %i14
%i47 = load i8, ptr %i46, align 1
%i48 = and i8 %i47, 15
%i49 = insertelement <4 x i8> poison, i8 %i48, i64 0
%i50 = shufflevector <4 x i8> %i49, <4 x i8> poison, <4 x i32> zeroinitializer
%i51 = zext <4 x i8> %i50 to <4 x i32>
%i52 = mul nuw nsw <4 x i32> %i45, %i51
%i53 = getelementptr inbounds i8, ptr %i8, i32 %i10
%i54 = load <4 x i8>, ptr %i53, align 1
%i55 = sext <4 x i8> %i54 to <4 x i32>
%i56 = mul nsw <4 x i32> %i52, %i55
%i57 = add <4 x i32> %i56, %i11
%i58 = add nuw i32 %i10, 4
%i59 = add nuw nsw <4 x i32> %i12, splat (i32 4)
%i60 = icmp eq i32 %i58, 256
br i1 %i60, label %bb61, label %bb9
bb61: ; preds = %bb9
%i62 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %i57)
%result = sitofp i32 %i62 to float
ret float %result
}
define hidden float @vec_dot_q4k_q8k(i32 noundef %arg, ptr noundef readonly %arg1, ptr noundef readonly %arg2) {
; CHECK-LABEL: vec_dot_q4k_q8k:
; CHECK: .functype vec_dot_q4k_q8k (i32, i32, i32) -> (f32)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0: # %bb
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.load8_u 0
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32.const 48
; CHECK-NEXT: i32.and
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.load8_u 8
; CHECK-NEXT: i32.const 15
; CHECK-NEXT: i32.and
; CHECK-NEXT: i32.or
; CHECK-NEXT: i32x4.splat
; CHECK-NEXT: local.get 2
; CHECK-NEXT: v128.load32_zero 4:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_s
; CHECK-NEXT: i32x4.extend_low_i16x8_s
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: local.get 1
; CHECK-NEXT: v128.load32_zero 16:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_u
; CHECK-NEXT: i32x4.extend_low_i16x8_u
; CHECK-NEXT: v128.const 15, 15, 15, 15
; CHECK-NEXT: v128.and
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i8x16.shuffle 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: f32.convert_i32_s
; CHECK-NEXT: # fallthrough-return
bb:
%i = lshr i32 %arg, 8
%i3 = icmp eq i32 %i, 0
br label %bb4
bb4: ; preds = %bb
%i5 = getelementptr inbounds %struct.quantized_block_q4k, ptr %arg1, i32 0
%i6 = getelementptr inbounds i8, ptr %i5, i32 4
%i7 = getelementptr inbounds i8, ptr %i5, i32 16
%i8 = getelementptr inbounds %struct.quantized_block_q8k, ptr %arg2, i32 0
%i9 = getelementptr inbounds i8, ptr %i8, i32 4
%i10 = getelementptr inbounds i8, ptr %i8, i32 260
br label %bb11
bb11: ; preds = %bb4
%i12 = phi i32 [ 0, %bb4 ]
%i13 = phi i32 [ 0, %bb4 ]
%i14 = phi i32 [ 0, %bb4 ]
%i15 = icmp ult i32 %i14, 4
%i16 = getelementptr inbounds i8, ptr %i6, i32 %i14
br label %bb17
bb17: ; preds = %bb11
%i18 = getelementptr inbounds i8, ptr %i16, i32 4
%i19 = load i8, ptr %i18, align 1
%i20 = and i8 %i19, 15
%i21 = getelementptr i8, ptr %i16, i32 -4
%i22 = load i8, ptr %i21, align 1
%i23 = lshr i8 %i22, 2
%i24 = and i8 %i23, 48
%i25 = or i8 %i24, %i20
%i26 = lshr i8 %i19, 4
%i27 = load i8, ptr %i16, align 1
%i28 = lshr i8 %i27, 2
%i29 = and i8 %i28, 48
%i30 = or i8 %i29, %i26
br label %bb31
bb31: ; preds = %bb17
%i32 = shl nuw nsw i32 %i14, 2
%i33 = and i32 %i32, 4
%i34 = insertelement <4 x i32> poison, i32 %i33, i64 0
%i35 = shufflevector <4 x i32> %i34, <4 x i32> poison, <4 x i32> zeroinitializer
%i36 = zext i8 %i25 to i32
%i37 = insertelement <4 x i32> poison, i32 %i36, i64 0
%i38 = shufflevector <4 x i32> %i37, <4 x i32> poison, <4 x i32> zeroinitializer
%i39 = insertelement <4 x i32> <i32 poison, i32 0, i32 0, i32 0>, i32 %i12, i64 0
%i40 = shl nuw nsw i32 %i14, 5
%i41 = getelementptr inbounds i8, ptr %i9, i32 %i40
%i42 = shl nuw nsw i32 %i14, 4
%i43 = and i32 %i42, 96
%i44 = getelementptr inbounds i8, ptr %i7, i32 %i43
%i45 = load <4 x i8>, ptr %i44, align 1
%i46 = zext <4 x i8> %i45 to <4 x i32>
%i47 = lshr <4 x i32> %i46, %i35
%i48 = and <4 x i32> %i47, splat (i32 15)
%i49 = load <4 x i8>, ptr %i41, align 1
%i50 = sext <4 x i8> %i49 to <4 x i32>
%i51 = mul nsw <4 x i32> %i38, %i50
%i52 = mul nsw <4 x i32> %i51, %i48
%i53 = add <4 x i32> %i52, %i39
%i54 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %i53)
%result = sitofp i32 %i54 to float
ret float %result
}
define hidden float @vec_dot_q4_1_q8_1(i32 noundef %arg, ptr noundef readonly %arg1, ptr noundef readonly %arg2) {
; CHECK-LABEL: vec_dot_q4_1_q8_1:
; CHECK: .functype vec_dot_q4_1_q8_1 (i32, i32, i32) -> (f32)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0: # %bb
; CHECK-NEXT: local.get 1
; CHECK-NEXT: v128.load32_zero 4:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_u
; CHECK-NEXT: i32x4.extend_low_i16x8_u
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: v128.const 15, 15, 15, 15
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.get 2
; CHECK-NEXT: v128.load32_zero 4:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_s
; CHECK-NEXT: i32x4.extend_low_i16x8_s
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32x4.shr_u
; CHECK-NEXT: local.get 2
; CHECK-NEXT: v128.load32_zero 20:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_s
; CHECK-NEXT: i32x4.extend_low_i16x8_s
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i8x16.shuffle 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: f32.convert_i32_s
; CHECK-NEXT: # fallthrough-return
bb:
%i = lshr i32 %arg, 5
%i3 = icmp eq i32 %i, 0
br label %bb4
bb4: ; preds = %bb
%i5 = getelementptr inbounds %struct.quantized_block_q4_1, ptr %arg1, i32 0
%i6 = getelementptr inbounds %struct.quantized_block_q8_1, ptr %arg2, i32 0
%i7 = getelementptr inbounds i8, ptr %i6, i32 4
%i8 = getelementptr inbounds i8, ptr %i5, i32 4
%i9 = load <4 x i8>, ptr %i8, align 1
%i10 = zext <4 x i8> %i9 to <4 x i32>
%i11 = and <4 x i32> %i10, splat (i32 15)
%i12 = load <4 x i8>, ptr %i7, align 1
%i13 = sext <4 x i8> %i12 to <4 x i32>
%i14 = mul nsw <4 x i32> %i11, %i13
%i15 = lshr <4 x i32> %i10, splat (i32 4)
%i16 = getelementptr inbounds i8, ptr %i6, i32 20
%i17 = load <4 x i8>, ptr %i16, align 1
%i18 = sext <4 x i8> %i17 to <4 x i32>
%i19 = mul nsw <4 x i32> %i15, %i18
%i20 = add nsw <4 x i32> %i14, %i19
%i21 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %i20)
%result = sitofp i32 %i21 to float
ret float %result
}
define hidden float @vec_dot_q5_K_q8_K(i32 noundef %arg, ptr noundef readonly %arg1, ptr noundef readonly %arg2) {
; CHECK-LABEL: vec_dot_q5_K_q8_K:
; CHECK: .functype vec_dot_q5_K_q8_K (i32, i32, i32) -> (f32)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0: # %bb
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.load8_u 0
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32.const 48
; CHECK-NEXT: i32.and
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.load8_u 8
; CHECK-NEXT: i32.const 15
; CHECK-NEXT: i32.and
; CHECK-NEXT: i32.or
; CHECK-NEXT: i32x4.splat
; CHECK-NEXT: local.get 2
; CHECK-NEXT: v128.load32_zero 4:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_s
; CHECK-NEXT: i32x4.extend_low_i16x8_s
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: local.get 1
; CHECK-NEXT: v128.load32_zero 16:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_u
; CHECK-NEXT: i32x4.extend_low_i16x8_u
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: v128.const 16, 16, 16, 16
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.get 1
; CHECK-NEXT: v128.load32_zero 48:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_u
; CHECK-NEXT: i32x4.extend_low_i16x8_u
; CHECK-NEXT: v128.const 15, 15, 15, 15
; CHECK-NEXT: v128.and
; CHECK-NEXT: v128.or
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i8x16.shuffle 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: f32.convert_i32_s
; CHECK-NEXT: # fallthrough-return
bb:
%i = lshr i32 %arg, 8
%i3 = icmp eq i32 %i, 0
br label %bb4
bb4: ; preds = %bb
%i5 = getelementptr inbounds %struct.quantized_block_q5k, ptr %arg1, i32 0
%i6 = getelementptr inbounds i8, ptr %i5, i32 4
%i7 = getelementptr inbounds i8, ptr %i5, i32 48
%i8 = getelementptr inbounds i8, ptr %i5, i32 16
%i9 = getelementptr inbounds %struct.quantized_block_q8k, ptr %arg2, i32 0
%i10 = getelementptr inbounds i8, ptr %i9, i32 4
%i11 = getelementptr inbounds i8, ptr %i9, i32 260
%i12 = load <4 x i8>, ptr %i8, align 1
%i13 = zext <4 x i8> %i12 to <4 x i32>
br label %bb14
bb14: ; preds = %bb4
%i15 = phi i32 [ 0, %bb4 ]
%i16 = phi i32 [ 0, %bb4 ]
%i17 = phi i32 [ 0, %bb4 ]
%i18 = icmp ult i32 %i17, 4
%i19 = getelementptr inbounds i8, ptr %i6, i32 %i17
br label %bb20
bb20: ; preds = %bb14
%i21 = getelementptr inbounds i8, ptr %i19, i32 4
%i22 = load i8, ptr %i21, align 1
%i23 = and i8 %i22, 15
%i24 = getelementptr i8, ptr %i19, i32 -4
%i25 = load i8, ptr %i24, align 1
%i26 = lshr i8 %i25, 2
%i27 = and i8 %i26, 48
%i28 = or i8 %i27, %i23
%i29 = lshr i8 %i22, 4
%i30 = load i8, ptr %i19, align 1
%i31 = lshr i8 %i30, 2
%i32 = and i8 %i31, 48
%i33 = or i8 %i32, %i29
br label %bb34
bb34: ; preds = %bb20
%i35 = insertelement <4 x i32> poison, i32 %i17, i64 0
%i36 = shufflevector <4 x i32> %i35, <4 x i32> poison, <4 x i32> zeroinitializer
%i37 = shl nuw nsw i32 %i17, 2
%i38 = and i32 %i37, 4
%i39 = insertelement <4 x i32> poison, i32 %i38, i64 0
%i40 = shufflevector <4 x i32> %i39, <4 x i32> poison, <4 x i32> zeroinitializer
%i41 = zext i8 %i28 to i32
%i42 = insertelement <4 x i32> poison, i32 %i41, i64 0
%i43 = shufflevector <4 x i32> %i42, <4 x i32> poison, <4 x i32> zeroinitializer
%i44 = insertelement <4 x i32> <i32 poison, i32 0, i32 0, i32 0>, i32 %i15, i64 0
%i45 = shl nuw nsw i32 %i17, 5
%i46 = getelementptr inbounds i8, ptr %i10, i32 %i45
%i47 = shl nuw nsw i32 %i17, 4
%i48 = and i32 %i47, 96
%i49 = getelementptr inbounds i8, ptr %i7, i32 %i48
%i50 = load <4 x i8>, ptr %i49, align 1
%i51 = zext <4 x i8> %i50 to <4 x i32>
%i52 = lshr <4 x i32> %i51, %i40
%i53 = and <4 x i32> %i52, splat (i32 15)
%i54 = lshr <4 x i32> %i13, %i36
%i55 = shl nuw nsw <4 x i32> %i54, splat (i32 4)
%i56 = and <4 x i32> %i55, splat (i32 16)
%i57 = or <4 x i32> %i56, %i53
%i58 = load <4 x i8>, ptr %i46, align 1
%i59 = sext <4 x i8> %i58 to <4 x i32>
%i60 = mul nsw <4 x i32> %i43, %i59
%i61 = mul nsw <4 x i32> %i60, %i57
%i62 = add <4 x i32> %i61, %i44
%i63 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %i62)
%result = sitofp i32 %i63 to float
ret float %result
}
define hidden float @vec_dot_q6_K_q8_K(i32 noundef %arg, ptr noundef readonly %arg1, ptr noundef readonly %arg2) {
; CHECK-LABEL: vec_dot_q6_K_q8_K:
; CHECK: .functype vec_dot_q6_K_q8_K (i32, i32, i32) -> (f32)
; CHECK-NEXT: .local i32, i32, v128, v128, v128, v128, v128, v128
; CHECK-NEXT: # %bb.0: # %bb
; CHECK-NEXT: block
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32.eqz
; CHECK-NEXT: br_if 0 # 0: down to label1
; CHECK-NEXT: # %bb.1: # %bb4
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 192
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.set 4
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 128
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.set 0
; CHECK-NEXT: v128.const 0, 1, 2, 3
; CHECK-NEXT: local.set 5
; CHECK-NEXT: v128.const 0, 0, 0, 0
; CHECK-NEXT: local.set 6
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.set 2
; CHECK-NEXT: .LBB5_2: # %bb10
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: loop # label2:
; CHECK-NEXT: local.get 3
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_zero 0:p2align=0
; CHECK-NEXT: i16x8.extend_low_i8x16_s
; CHECK-NEXT: local.get 4
; CHECK-NEXT: local.get 5
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32x4.shr_u
; CHECK-NEXT: local.tee 7
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load8_splat 0
; CHECK-NEXT: i16x8.extend_low_i8x16_s
; CHECK-NEXT: i32x4.extmul_low_i16x8_s
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 5
; CHECK-NEXT: i32.const 7
; CHECK-NEXT: i32x4.shr_u
; CHECK-NEXT: local.tee 8
; CHECK-NEXT: i32.const 5
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: local.tee 9
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 5
; CHECK-NEXT: v128.const 31, 31, 31, 31
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.tee 10
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load8_splat 0
; CHECK-NEXT: v128.load8_lane 0, 1
; CHECK-NEXT: v128.load8_lane 0, 2
; CHECK-NEXT: v128.load8_lane 0, 3
; CHECK-NEXT: i16x8.extend_low_i8x16_u
; CHECK-NEXT: i32x4.extend_low_i16x8_u
; CHECK-NEXT: local.tee 9
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: local.get 7
; CHECK-NEXT: v128.const 6, 6, 6, 6
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.tee 10
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.splat
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.replace_lane 1
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.replace_lane 2
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.replace_lane 3
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: v128.const 48, 48, 48, 48
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 8
; CHECK-NEXT: i32.const 6
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: local.tee 9
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 5
; CHECK-NEXT: v128.const 63, 63, 63, 63
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.tee 10
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load8_splat 0
; CHECK-NEXT: v128.load8_lane 0, 1
; CHECK-NEXT: v128.load8_lane 0, 2
; CHECK-NEXT: v128.load8_lane 0, 3
; CHECK-NEXT: i16x8.extend_low_i8x16_u
; CHECK-NEXT: i32x4.extend_low_i16x8_u
; CHECK-NEXT: local.tee 9
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: local.get 7
; CHECK-NEXT: v128.const 4, 4, 4, 4
; CHECK-NEXT: local.tee 8
; CHECK-NEXT: v128.and
; CHECK-NEXT: local.tee 10
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.splat
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 1
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.replace_lane 1
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 2
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.replace_lane 2
; CHECK-NEXT: local.get 9
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: local.get 10
; CHECK-NEXT: i32x4.extract_lane 3
; CHECK-NEXT: i32.shr_u
; CHECK-NEXT: i32x4.replace_lane 3
; CHECK-NEXT: v128.const 15, 15, 15, 15
; CHECK-NEXT: v128.and
; CHECK-NEXT: v128.or
; CHECK-NEXT: v128.const -32, -32, -32, -32
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: i32x4.mul
; CHECK-NEXT: local.get 6
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.set 6
; CHECK-NEXT: local.get 5
; CHECK-NEXT: local.get 8
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.set 5
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.tee 2
; CHECK-NEXT: i32.const 256
; CHECK-NEXT: i32.ne
; CHECK-NEXT: br_if 0 # 0: up to label2
; CHECK-NEXT: # %bb.3: # %bb94
; CHECK-NEXT: end_loop
; CHECK-NEXT: local.get 6
; CHECK-NEXT: local.get 6
; CHECK-NEXT: local.get 5
; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: local.tee 5
; CHECK-NEXT: local.get 5
; CHECK-NEXT: local.get 5
; CHECK-NEXT: i8x16.shuffle 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
; CHECK-NEXT: i32x4.add
; CHECK-NEXT: i32x4.extract_lane 0
; CHECK-NEXT: f32.convert_i32_s
; CHECK-NEXT: return
; CHECK-NEXT: .LBB5_4: # %bb96
; CHECK-NEXT: end_block # label1:
; CHECK-NEXT: f32.const 0x0p0
; CHECK-NEXT: # fallthrough-return
bb:
%i = lshr i32 %arg, 8
%i3 = icmp eq i32 %i, 0
br i1 %i3, label %bb96, label %bb4
bb4: ; preds = %bb
%i5 = getelementptr inbounds %struct.quantized_block_q6k, ptr %arg1, i32 0
%i6 = getelementptr inbounds i8, ptr %i5, i32 128
%i7 = getelementptr inbounds i8, ptr %i5, i32 192
%i8 = getelementptr inbounds %struct.quantized_block_q8k, ptr %arg2, i32 0
%i9 = getelementptr inbounds i8, ptr %i8, i32 4
br label %bb10
bb10: ; preds = %bb10, %bb4
%i11 = phi i32 [ 0, %bb4 ], [ %i91, %bb10 ]
%i12 = phi <4 x i32> [ zeroinitializer, %bb4 ], [ %i90, %bb10 ]
%i13 = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, %bb4 ], [ %i92, %bb10 ]
%i14 = lshr <4 x i32> %i13, splat (i32 7)
%i15 = shl nuw nsw <4 x i32> %i14, splat (i32 6)
%i16 = extractelement <4 x i32> %i15, i64 0
%i17 = extractelement <4 x i32> %i15, i64 1
%i18 = extractelement <4 x i32> %i15, i64 2
%i19 = extractelement <4 x i32> %i15, i64 3
%i20 = and <4 x i32> %i13, splat (i32 63)
%i21 = extractelement <4 x i32> %i20, i64 0
%i22 = extractelement <4 x i32> %i20, i64 1
%i23 = extractelement <4 x i32> %i20, i64 2
%i24 = extractelement <4 x i32> %i20, i64 3
%i25 = shl nuw nsw <4 x i32> %i14, splat (i32 5)
%i26 = extractelement <4 x i32> %i25, i64 0
%i27 = extractelement <4 x i32> %i25, i64 1
%i28 = extractelement <4 x i32> %i25, i64 2
%i29 = extractelement <4 x i32> %i25, i64 3
%i30 = and <4 x i32> %i13, splat (i32 31)
%i31 = extractelement <4 x i32> %i30, i64 0
%i32 = extractelement <4 x i32> %i30, i64 1
%i33 = extractelement <4 x i32> %i30, i64 2
%i34 = extractelement <4 x i32> %i30, i64 3
%i35 = lshr <4 x i32> %i13, splat (i32 4)
%i36 = extractelement <4 x i32> %i35, i64 0
%i37 = and <4 x i32> %i35, splat (i32 4)
%i38 = and <4 x i32> %i35, splat (i32 6)
%i39 = getelementptr inbounds i8, ptr %i5, i32 %i16
%i40 = getelementptr inbounds i8, ptr %i5, i32 %i17
%i41 = getelementptr inbounds i8, ptr %i5, i32 %i18
%i42 = getelementptr inbounds i8, ptr %i5, i32 %i19
%i43 = getelementptr inbounds i8, ptr %i39, i32 %i21
%i44 = getelementptr inbounds i8, ptr %i40, i32 %i22
%i45 = getelementptr inbounds i8, ptr %i41, i32 %i23
%i46 = getelementptr inbounds i8, ptr %i42, i32 %i24
%i47 = load i8, ptr %i43, align 1
%i48 = load i8, ptr %i44, align 1
%i49 = load i8, ptr %i45, align 1
%i50 = load i8, ptr %i46, align 1
%i51 = insertelement <4 x i8> poison, i8 %i47, i64 0
%i52 = insertelement <4 x i8> %i51, i8 %i48, i64 1
%i53 = insertelement <4 x i8> %i52, i8 %i49, i64 2
%i54 = insertelement <4 x i8> %i53, i8 %i50, i64 3
%i55 = zext <4 x i8> %i54 to <4 x i32>
%i56 = lshr <4 x i32> %i55, %i37
%i57 = and <4 x i32> %i56, splat (i32 15)
%i58 = getelementptr inbounds i8, ptr %i6, i32 %i26
%i59 = getelementptr inbounds i8, ptr %i6, i32 %i27
%i60 = getelementptr inbounds i8, ptr %i6, i32 %i28
%i61 = getelementptr inbounds i8, ptr %i6, i32 %i29
%i62 = getelementptr inbounds i8, ptr %i58, i32 %i31
%i63 = getelementptr inbounds i8, ptr %i59, i32 %i32
%i64 = getelementptr inbounds i8, ptr %i60, i32 %i33
%i65 = getelementptr inbounds i8, ptr %i61, i32 %i34
%i66 = load i8, ptr %i62, align 1
%i67 = load i8, ptr %i63, align 1
%i68 = load i8, ptr %i64, align 1
%i69 = load i8, ptr %i65, align 1
%i70 = insertelement <4 x i8> poison, i8 %i66, i64 0
%i71 = insertelement <4 x i8> %i70, i8 %i67, i64 1
%i72 = insertelement <4 x i8> %i71, i8 %i68, i64 2
%i73 = insertelement <4 x i8> %i72, i8 %i69, i64 3
%i74 = zext <4 x i8> %i73 to <4 x i32>
%i75 = lshr <4 x i32> %i74, %i38
%i76 = shl nuw nsw <4 x i32> %i75, splat (i32 4)
%i77 = and <4 x i32> %i76, splat (i32 48)
%i78 = or <4 x i32> %i57, splat (i32 -32)
%i79 = add nsw <4 x i32> %i78, %i77
%i80 = getelementptr inbounds i8, ptr %i7, i32 %i36
%i81 = load i8, ptr %i80, align 1
%i82 = insertelement <4 x i8> poison, i8 %i81, i64 0
%i83 = shufflevector <4 x i8> %i82, <4 x i8> poison, <4 x i32> zeroinitializer
%i84 = sext <4 x i8> %i83 to <4 x i32>
%i85 = getelementptr inbounds i8, ptr %i9, i32 %i11
%i86 = load <4 x i8>, ptr %i85, align 1
%i87 = sext <4 x i8> %i86 to <4 x i32>
%i88 = mul nsw <4 x i32> %i87, %i84
%i89 = mul nsw <4 x i32> %i88, %i79
%i90 = add <4 x i32> %i89, %i12
%i91 = add nuw i32 %i11, 4
%i92 = add nuw nsw <4 x i32> %i13, splat (i32 4)
%i93 = icmp eq i32 %i91, 256
br i1 %i93, label %bb94, label %bb10
bb94: ; preds = %bb10
%i95 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %i90)
%result = sitofp i32 %i95 to float
ret float %result
bb96: ; preds = %bb
ret float 0.000000e+00
}
; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>) #0
attributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }