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