| ; 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) } |