| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature |
| // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -target-feature +fullfp16 -target-feature +v8.2a\ |
| // RUN: -flax-vector-conversions=none -S -disable-O0-optnone -emit-llvm -o - %s \ |
| // RUN: | opt -S -passes=mem2reg \ |
| // RUN: | FileCheck %s |
| |
| // REQUIRES: aarch64-registered-target |
| |
| #include <arm_neon.h> |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vabs_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VABS1_I:%.*]] = call <4 x half> @llvm.fabs.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VABS1_I]] |
| // |
| float16x4_t test_vabs_f16(float16x4_t a) { |
| return vabs_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vabsq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VABS1_I:%.*]] = call <8 x half> @llvm.fabs.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VABS1_I]] |
| // |
| float16x8_t test_vabsq_f16(float16x8_t a) { |
| return vabsq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vceqz_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq <4 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCEQZ_I:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[VCEQZ_I]] |
| // |
| uint16x4_t test_vceqz_f16(float16x4_t a) { |
| return vceqz_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vceqzq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq <8 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCEQZ_I:%.*]] = sext <8 x i1> [[TMP1]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[VCEQZ_I]] |
| // |
| uint16x8_t test_vceqzq_f16(float16x8_t a) { |
| return vceqzq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcgez_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp oge <4 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCGEZ_I:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[VCGEZ_I]] |
| // |
| uint16x4_t test_vcgez_f16(float16x4_t a) { |
| return vcgez_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcgezq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp oge <8 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCGEZ_I:%.*]] = sext <8 x i1> [[TMP1]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[VCGEZ_I]] |
| // |
| uint16x8_t test_vcgezq_f16(float16x8_t a) { |
| return vcgezq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcgtz_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp ogt <4 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCGTZ_I:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[VCGTZ_I]] |
| // |
| uint16x4_t test_vcgtz_f16(float16x4_t a) { |
| return vcgtz_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcgtzq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp ogt <8 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCGTZ_I:%.*]] = sext <8 x i1> [[TMP1]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[VCGTZ_I]] |
| // |
| uint16x8_t test_vcgtzq_f16(float16x8_t a) { |
| return vcgtzq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vclez_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp ole <4 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCLEZ_I:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[VCLEZ_I]] |
| // |
| uint16x4_t test_vclez_f16(float16x4_t a) { |
| return vclez_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vclezq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp ole <8 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCLEZ_I:%.*]] = sext <8 x i1> [[TMP1]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[VCLEZ_I]] |
| // |
| uint16x8_t test_vclezq_f16(float16x8_t a) { |
| return vclezq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcltz_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp olt <4 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCLTZ_I:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[VCLTZ_I]] |
| // |
| uint16x4_t test_vcltz_f16(float16x4_t a) { |
| return vcltz_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcltzq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = fcmp olt <8 x half> [[A]], zeroinitializer |
| // CHECK-NEXT: [[VCLTZ_I:%.*]] = sext <8 x i1> [[TMP1]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[VCLTZ_I]] |
| // |
| uint16x8_t test_vcltzq_f16(float16x8_t a) { |
| return vcltzq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvt_f16_s16 |
| // CHECK-SAME: (<4 x i16> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVT_I:%.*]] = sitofp <4 x i16> [[A]] to <4 x half> |
| // CHECK-NEXT: ret <4 x half> [[VCVT_I]] |
| // |
| float16x4_t test_vcvt_f16_s16 (int16x4_t a) { |
| return vcvt_f16_s16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_f16_s16 |
| // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVT_I:%.*]] = sitofp <8 x i16> [[A]] to <8 x half> |
| // CHECK-NEXT: ret <8 x half> [[VCVT_I]] |
| // |
| float16x8_t test_vcvtq_f16_s16 (int16x8_t a) { |
| return vcvtq_f16_s16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvt_f16_u16 |
| // CHECK-SAME: (<4 x i16> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVT_I:%.*]] = uitofp <4 x i16> [[A]] to <4 x half> |
| // CHECK-NEXT: ret <4 x half> [[VCVT_I]] |
| // |
| float16x4_t test_vcvt_f16_u16 (uint16x4_t a) { |
| return vcvt_f16_u16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_f16_u16 |
| // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVT_I:%.*]] = uitofp <8 x i16> [[A]] to <8 x half> |
| // CHECK-NEXT: ret <8 x half> [[VCVT_I]] |
| // |
| float16x8_t test_vcvtq_f16_u16 (uint16x8_t a) { |
| return vcvtq_f16_u16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvt_s16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTZ1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtzs.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTZ1_I]] |
| // |
| int16x4_t test_vcvt_s16_f16 (float16x4_t a) { |
| return vcvt_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_s16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVTZ1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtzs.v8i16.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCVTZ1_I]] |
| // |
| int16x8_t test_vcvtq_s16_f16 (float16x8_t a) { |
| return vcvtq_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvt_u16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTZ1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtzu.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTZ1_I]] |
| // |
| uint16x4_t test_vcvt_u16_f16 (float16x4_t a) { |
| return vcvt_u16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_u16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVTZ1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtzu.v8i16.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCVTZ1_I]] |
| // |
| uint16x8_t test_vcvtq_u16_f16 (float16x8_t a) { |
| return vcvtq_u16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvta_s16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTA1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtas.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTA1_I]] |
| // |
| int16x4_t test_vcvta_s16_f16 (float16x4_t a) { |
| return vcvta_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvta_u16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTA1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtau.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTA1_I]] |
| // |
| uint16x4_t test_vcvta_u16_f16 (float16x4_t a) { |
| return vcvta_u16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtaq_s16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVTA1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtas.v8i16.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCVTA1_I]] |
| // |
| int16x8_t test_vcvtaq_s16_f16 (float16x8_t a) { |
| return vcvtaq_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtm_s16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTM1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtms.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTM1_I]] |
| // |
| int16x4_t test_vcvtm_s16_f16 (float16x4_t a) { |
| return vcvtm_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtmq_s16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVTM1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtms.v8i16.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCVTM1_I]] |
| // |
| int16x8_t test_vcvtmq_s16_f16 (float16x8_t a) { |
| return vcvtmq_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtm_u16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTM1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtmu.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTM1_I]] |
| // |
| uint16x4_t test_vcvtm_u16_f16 (float16x4_t a) { |
| return vcvtm_u16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtmq_u16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVTM1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtmu.v8i16.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCVTM1_I]] |
| // |
| uint16x8_t test_vcvtmq_u16_f16 (float16x8_t a) { |
| return vcvtmq_u16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtn_s16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTN1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtns.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTN1_I]] |
| // |
| int16x4_t test_vcvtn_s16_f16 (float16x4_t a) { |
| return vcvtn_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtnq_s16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVTN1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtns.v8i16.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCVTN1_I]] |
| // |
| int16x8_t test_vcvtnq_s16_f16 (float16x8_t a) { |
| return vcvtnq_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtn_u16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTN1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtnu.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTN1_I]] |
| // |
| uint16x4_t test_vcvtn_u16_f16 (float16x4_t a) { |
| return vcvtn_u16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtnq_u16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVTN1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtnu.v8i16.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCVTN1_I]] |
| // |
| uint16x8_t test_vcvtnq_u16_f16 (float16x8_t a) { |
| return vcvtnq_u16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtp_s16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTP1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtps.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTP1_I]] |
| // |
| int16x4_t test_vcvtp_s16_f16 (float16x4_t a) { |
| return vcvtp_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtpq_s16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVTP1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtps.v8i16.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCVTP1_I]] |
| // |
| int16x8_t test_vcvtpq_s16_f16 (float16x8_t a) { |
| return vcvtpq_s16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtp_u16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVTP1_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.fcvtpu.v4i16.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCVTP1_I]] |
| // |
| uint16x4_t test_vcvtp_u16_f16 (float16x4_t a) { |
| return vcvtp_u16_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtpq_u16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVTP1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtpu.v8i16.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCVTP1_I]] |
| // |
| uint16x8_t test_vcvtpq_u16_f16 (float16x8_t a) { |
| return vcvtpq_u16_f16(a); |
| } |
| |
| // FIXME: Fix the zero constant when fp16 non-storage-only type becomes available. |
| // CHECK-LABEL: define {{[^@]+}}@test_vneg_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <4 x half> [[A]] |
| // CHECK-NEXT: ret <4 x half> [[FNEG_I]] |
| // |
| float16x4_t test_vneg_f16(float16x4_t a) { |
| return vneg_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vnegq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <8 x half> [[A]] |
| // CHECK-NEXT: ret <8 x half> [[FNEG_I]] |
| // |
| float16x8_t test_vnegq_f16(float16x8_t a) { |
| return vnegq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrecpe_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VRECPE_V1_I:%.*]] = call <4 x half> @llvm.aarch64.neon.frecpe.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VRECPE_V1_I]] |
| // |
| float16x4_t test_vrecpe_f16(float16x4_t a) { |
| return vrecpe_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrecpeq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VRECPEQ_V1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.frecpe.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VRECPEQ_V1_I]] |
| // |
| float16x8_t test_vrecpeq_f16(float16x8_t a) { |
| return vrecpeq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrnd_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VRNDZ1_I:%.*]] = call <4 x half> @llvm.trunc.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VRNDZ1_I]] |
| // |
| float16x4_t test_vrnd_f16(float16x4_t a) { |
| return vrnd_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VRNDZ1_I:%.*]] = call <8 x half> @llvm.trunc.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VRNDZ1_I]] |
| // |
| float16x8_t test_vrndq_f16(float16x8_t a) { |
| return vrndq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrnda_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VRNDA1_I:%.*]] = call <4 x half> @llvm.round.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VRNDA1_I]] |
| // |
| float16x4_t test_vrnda_f16(float16x4_t a) { |
| return vrnda_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndaq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VRNDA1_I:%.*]] = call <8 x half> @llvm.round.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VRNDA1_I]] |
| // |
| float16x8_t test_vrndaq_f16(float16x8_t a) { |
| return vrndaq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndi_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VRNDI_V1_I:%.*]] = call <4 x half> @llvm.nearbyint.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VRNDI_V1_I]] |
| // |
| float16x4_t test_vrndi_f16(float16x4_t a) { |
| return vrndi_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndiq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VRNDIQ_V1_I:%.*]] = call <8 x half> @llvm.nearbyint.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VRNDIQ_V1_I]] |
| // |
| float16x8_t test_vrndiq_f16(float16x8_t a) { |
| return vrndiq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndm_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VRNDM1_I:%.*]] = call <4 x half> @llvm.floor.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VRNDM1_I]] |
| // |
| float16x4_t test_vrndm_f16(float16x4_t a) { |
| return vrndm_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndmq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VRNDM1_I:%.*]] = call <8 x half> @llvm.floor.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VRNDM1_I]] |
| // |
| float16x8_t test_vrndmq_f16(float16x8_t a) { |
| return vrndmq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndn_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VRNDN1_I:%.*]] = call <4 x half> @llvm.roundeven.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VRNDN1_I]] |
| // |
| float16x4_t test_vrndn_f16(float16x4_t a) { |
| return vrndn_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndnq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VRNDN1_I:%.*]] = call <8 x half> @llvm.roundeven.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VRNDN1_I]] |
| // |
| float16x8_t test_vrndnq_f16(float16x8_t a) { |
| return vrndnq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndp_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VRNDP1_I:%.*]] = call <4 x half> @llvm.ceil.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VRNDP1_I]] |
| // |
| float16x4_t test_vrndp_f16(float16x4_t a) { |
| return vrndp_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndpq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VRNDP1_I:%.*]] = call <8 x half> @llvm.ceil.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VRNDP1_I]] |
| // |
| float16x8_t test_vrndpq_f16(float16x8_t a) { |
| return vrndpq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndx_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VRNDX1_I:%.*]] = call <4 x half> @llvm.rint.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VRNDX1_I]] |
| // |
| float16x4_t test_vrndx_f16(float16x4_t a) { |
| return vrndx_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrndxq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VRNDX1_I:%.*]] = call <8 x half> @llvm.rint.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VRNDX1_I]] |
| // |
| float16x8_t test_vrndxq_f16(float16x8_t a) { |
| return vrndxq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrsqrte_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VRSQRTE_V1_I:%.*]] = call <4 x half> @llvm.aarch64.neon.frsqrte.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VRSQRTE_V1_I]] |
| // |
| float16x4_t test_vrsqrte_f16(float16x4_t a) { |
| return vrsqrte_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrsqrteq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VRSQRTEQ_V1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.frsqrte.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VRSQRTEQ_V1_I]] |
| // |
| float16x8_t test_vrsqrteq_f16(float16x8_t a) { |
| return vrsqrteq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vsqrt_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VSQRT_I:%.*]] = call <4 x half> @llvm.sqrt.v4f16(<4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[VSQRT_I]] |
| // |
| float16x4_t test_vsqrt_f16(float16x4_t a) { |
| return vsqrt_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vsqrtq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VSQRT_I:%.*]] = call <8 x half> @llvm.sqrt.v8f16(<8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[VSQRT_I]] |
| // |
| float16x8_t test_vsqrtq_f16(float16x8_t a) { |
| return vsqrtq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vadd_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[ADD_I:%.*]] = fadd <4 x half> [[A]], [[B]] |
| // CHECK-NEXT: ret <4 x half> [[ADD_I]] |
| // |
| float16x4_t test_vadd_f16(float16x4_t a, float16x4_t b) { |
| return vadd_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vaddq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[ADD_I:%.*]] = fadd <8 x half> [[A]], [[B]] |
| // CHECK-NEXT: ret <8 x half> [[ADD_I]] |
| // |
| float16x8_t test_vaddq_f16(float16x8_t a, float16x8_t b) { |
| return vaddq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vabd_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VABD2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fabd.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VABD2_I]] |
| // |
| float16x4_t test_vabd_f16(float16x4_t a, float16x4_t b) { |
| return vabd_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vabdq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VABD2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fabd.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VABD2_I]] |
| // |
| float16x8_t test_vabdq_f16(float16x8_t a, float16x8_t b) { |
| return vabdq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcage_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VCAGE_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.facge.v4i16.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCAGE_V2_I]] |
| // |
| uint16x4_t test_vcage_f16(float16x4_t a, float16x4_t b) { |
| return vcage_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcageq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VCAGEQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.facge.v8i16.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCAGEQ_V2_I]] |
| // |
| uint16x8_t test_vcageq_f16(float16x8_t a, float16x8_t b) { |
| return vcageq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcagt_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VCAGT_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.facgt.v4i16.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCAGT_V2_I]] |
| // |
| uint16x4_t test_vcagt_f16(float16x4_t a, float16x4_t b) { |
| return vcagt_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcagtq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VCAGTQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.facgt.v8i16.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCAGTQ_V2_I]] |
| // |
| uint16x8_t test_vcagtq_f16(float16x8_t a, float16x8_t b) { |
| return vcagtq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcale_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VCALE_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.facge.v4i16.v4f16(<4 x half> [[B]], <4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCALE_V2_I]] |
| // |
| uint16x4_t test_vcale_f16(float16x4_t a, float16x4_t b) { |
| return vcale_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcaleq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VCALEQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.facge.v8i16.v8f16(<8 x half> [[B]], <8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCALEQ_V2_I]] |
| // |
| uint16x8_t test_vcaleq_f16(float16x8_t a, float16x8_t b) { |
| return vcaleq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcalt_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VCALT_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.facgt.v4i16.v4f16(<4 x half> [[B]], <4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x i16> [[VCALT_V2_I]] |
| // |
| uint16x4_t test_vcalt_f16(float16x4_t a, float16x4_t b) { |
| return vcalt_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcaltq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VCALTQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.facgt.v8i16.v8f16(<8 x half> [[B]], <8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x i16> [[VCALTQ_V2_I]] |
| // |
| uint16x8_t test_vcaltq_f16(float16x8_t a, float16x8_t b) { |
| return vcaltq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vceq_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp oeq <4 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <4 x i1> [[CMP_I]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[SEXT_I]] |
| // |
| uint16x4_t test_vceq_f16(float16x4_t a, float16x4_t b) { |
| return vceq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vceqq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp oeq <8 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[SEXT_I]] |
| // |
| uint16x8_t test_vceqq_f16(float16x8_t a, float16x8_t b) { |
| return vceqq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcge_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp oge <4 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <4 x i1> [[CMP_I]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[SEXT_I]] |
| // |
| uint16x4_t test_vcge_f16(float16x4_t a, float16x4_t b) { |
| return vcge_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcgeq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp oge <8 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[SEXT_I]] |
| // |
| uint16x8_t test_vcgeq_f16(float16x8_t a, float16x8_t b) { |
| return vcgeq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcgt_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp ogt <4 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <4 x i1> [[CMP_I]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[SEXT_I]] |
| // |
| uint16x4_t test_vcgt_f16(float16x4_t a, float16x4_t b) { |
| return vcgt_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcgtq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp ogt <8 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[SEXT_I]] |
| // |
| uint16x8_t test_vcgtq_f16(float16x8_t a, float16x8_t b) { |
| return vcgtq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcle_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp ole <4 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <4 x i1> [[CMP_I]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[SEXT_I]] |
| // |
| uint16x4_t test_vcle_f16(float16x4_t a, float16x4_t b) { |
| return vcle_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcleq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp ole <8 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[SEXT_I]] |
| // |
| uint16x8_t test_vcleq_f16(float16x8_t a, float16x8_t b) { |
| return vcleq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vclt_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp olt <4 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <4 x i1> [[CMP_I]] to <4 x i16> |
| // CHECK-NEXT: ret <4 x i16> [[SEXT_I]] |
| // |
| uint16x4_t test_vclt_f16(float16x4_t a, float16x4_t b) { |
| return vclt_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcltq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CMP_I:%.*]] = fcmp olt <8 x half> [[A]], [[B]] |
| // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> |
| // CHECK-NEXT: ret <8 x i16> [[SEXT_I]] |
| // |
| uint16x8_t test_vcltq_f16(float16x8_t a, float16x8_t b) { |
| return vcltq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvt_n_f16_s16 |
| // CHECK-SAME: (<4 x i16> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16> |
| // CHECK-NEXT: [[VCVT_N1:%.*]] = call <4 x half> @llvm.aarch64.neon.vcvtfxs2fp.v4f16.v4i16(<4 x i16> [[VCVT_N]], i32 2) |
| // CHECK-NEXT: ret <4 x half> [[VCVT_N1]] |
| // |
| float16x4_t test_vcvt_n_f16_s16(int16x4_t a) { |
| return vcvt_n_f16_s16(a, 2); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_n_f16_s16 |
| // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16> |
| // CHECK-NEXT: [[VCVT_N1:%.*]] = call <8 x half> @llvm.aarch64.neon.vcvtfxs2fp.v8f16.v8i16(<8 x i16> [[VCVT_N]], i32 2) |
| // CHECK-NEXT: ret <8 x half> [[VCVT_N1]] |
| // |
| float16x8_t test_vcvtq_n_f16_s16(int16x8_t a) { |
| return vcvtq_n_f16_s16(a, 2); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvt_n_f16_u16 |
| // CHECK-SAME: (<4 x i16> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16> |
| // CHECK-NEXT: [[VCVT_N1:%.*]] = call <4 x half> @llvm.aarch64.neon.vcvtfxu2fp.v4f16.v4i16(<4 x i16> [[VCVT_N]], i32 2) |
| // CHECK-NEXT: ret <4 x half> [[VCVT_N1]] |
| // |
| float16x4_t test_vcvt_n_f16_u16(uint16x4_t a) { |
| return vcvt_n_f16_u16(a, 2); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_n_f16_u16 |
| // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16> |
| // CHECK-NEXT: [[VCVT_N1:%.*]] = call <8 x half> @llvm.aarch64.neon.vcvtfxu2fp.v8f16.v8i16(<8 x i16> [[VCVT_N]], i32 2) |
| // CHECK-NEXT: ret <8 x half> [[VCVT_N1]] |
| // |
| float16x8_t test_vcvtq_n_f16_u16(uint16x8_t a) { |
| return vcvtq_n_f16_u16(a, 2); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvt_n_s16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[VCVT_N1:%.*]] = call <4 x i16> @llvm.aarch64.neon.vcvtfp2fxs.v4i16.v4f16(<4 x half> [[VCVT_N]], i32 2) |
| // CHECK-NEXT: ret <4 x i16> [[VCVT_N1]] |
| // |
| int16x4_t test_vcvt_n_s16_f16(float16x4_t a) { |
| return vcvt_n_s16_f16(a, 2); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_n_s16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[VCVT_N1:%.*]] = call <8 x i16> @llvm.aarch64.neon.vcvtfp2fxs.v8i16.v8f16(<8 x half> [[VCVT_N]], i32 2) |
| // CHECK-NEXT: ret <8 x i16> [[VCVT_N1]] |
| // |
| int16x8_t test_vcvtq_n_s16_f16(float16x8_t a) { |
| return vcvtq_n_s16_f16(a, 2); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvt_n_u16_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[VCVT_N1:%.*]] = call <4 x i16> @llvm.aarch64.neon.vcvtfp2fxu.v4i16.v4f16(<4 x half> [[VCVT_N]], i32 2) |
| // CHECK-NEXT: ret <4 x i16> [[VCVT_N1]] |
| // |
| uint16x4_t test_vcvt_n_u16_f16(float16x4_t a) { |
| return vcvt_n_u16_f16(a, 2); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_n_u16_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[VCVT_N1:%.*]] = call <8 x i16> @llvm.aarch64.neon.vcvtfp2fxu.v8i16.v8f16(<8 x half> [[VCVT_N]], i32 2) |
| // CHECK-NEXT: ret <8 x i16> [[VCVT_N1]] |
| // |
| uint16x8_t test_vcvtq_n_u16_f16(float16x8_t a) { |
| return vcvtq_n_u16_f16(a, 2); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vdiv_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[DIV_I:%.*]] = fdiv <4 x half> [[A]], [[B]] |
| // CHECK-NEXT: ret <4 x half> [[DIV_I]] |
| // |
| float16x4_t test_vdiv_f16(float16x4_t a, float16x4_t b) { |
| return vdiv_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vdivq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[DIV_I:%.*]] = fdiv <8 x half> [[A]], [[B]] |
| // CHECK-NEXT: ret <8 x half> [[DIV_I]] |
| // |
| float16x8_t test_vdivq_f16(float16x8_t a, float16x8_t b) { |
| return vdivq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmax_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VMAX2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fmax.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VMAX2_I]] |
| // |
| float16x4_t test_vmax_f16(float16x4_t a, float16x4_t b) { |
| return vmax_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmaxq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VMAX2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fmax.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VMAX2_I]] |
| // |
| float16x8_t test_vmaxq_f16(float16x8_t a, float16x8_t b) { |
| return vmaxq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmaxnm_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VMAXNM2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fmaxnm.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VMAXNM2_I]] |
| // |
| float16x4_t test_vmaxnm_f16(float16x4_t a, float16x4_t b) { |
| return vmaxnm_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmaxnmq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VMAXNM2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fmaxnm.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VMAXNM2_I]] |
| // |
| float16x8_t test_vmaxnmq_f16(float16x8_t a, float16x8_t b) { |
| return vmaxnmq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmin_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VMIN2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fmin.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VMIN2_I]] |
| // |
| float16x4_t test_vmin_f16(float16x4_t a, float16x4_t b) { |
| return vmin_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vminq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VMIN2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fmin.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VMIN2_I]] |
| // |
| float16x8_t test_vminq_f16(float16x8_t a, float16x8_t b) { |
| return vminq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vminnm_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VMINNM2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fminnm.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VMINNM2_I]] |
| // |
| float16x4_t test_vminnm_f16(float16x4_t a, float16x4_t b) { |
| return vminnm_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vminnmq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VMINNM2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fminnm.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VMINNM2_I]] |
| // |
| float16x8_t test_vminnmq_f16(float16x8_t a, float16x8_t b) { |
| return vminnmq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmul_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[MUL_I:%.*]] = fmul <4 x half> [[A]], [[B]] |
| // CHECK-NEXT: ret <4 x half> [[MUL_I]] |
| // |
| float16x4_t test_vmul_f16(float16x4_t a, float16x4_t b) { |
| return vmul_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[MUL_I:%.*]] = fmul <8 x half> [[A]], [[B]] |
| // CHECK-NEXT: ret <8 x half> [[MUL_I]] |
| // |
| float16x8_t test_vmulq_f16(float16x8_t a, float16x8_t b) { |
| return vmulq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulx_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VMULX2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fmulx.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VMULX2_I]] |
| // |
| float16x4_t test_vmulx_f16(float16x4_t a, float16x4_t b) { |
| return vmulx_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulxq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VMULX2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fmulx.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VMULX2_I]] |
| // |
| float16x8_t test_vmulxq_f16(float16x8_t a, float16x8_t b) { |
| return vmulxq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpadd_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VPADD_V2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.faddp.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: [[VPADD_V3_I:%.*]] = bitcast <4 x half> [[VPADD_V2_I]] to <8 x i8> |
| // CHECK-NEXT: ret <4 x half> [[VPADD_V2_I]] |
| // |
| float16x4_t test_vpadd_f16(float16x4_t a, float16x4_t b) { |
| return vpadd_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpaddq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VPADDQ_V2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.faddp.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: [[VPADDQ_V3_I:%.*]] = bitcast <8 x half> [[VPADDQ_V2_I]] to <16 x i8> |
| // CHECK-NEXT: ret <8 x half> [[VPADDQ_V2_I]] |
| // |
| float16x8_t test_vpaddq_f16(float16x8_t a, float16x8_t b) { |
| return vpaddq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpmax_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VPMAX2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fmaxp.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VPMAX2_I]] |
| // |
| float16x4_t test_vpmax_f16(float16x4_t a, float16x4_t b) { |
| return vpmax_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpmaxq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VPMAX2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fmaxp.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VPMAX2_I]] |
| // |
| float16x8_t test_vpmaxq_f16(float16x8_t a, float16x8_t b) { |
| return vpmaxq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpmaxnm_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VPMAXNM2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fmaxnmp.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VPMAXNM2_I]] |
| // |
| float16x4_t test_vpmaxnm_f16(float16x4_t a, float16x4_t b) { |
| return vpmaxnm_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpmaxnmq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VPMAXNM2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fmaxnmp.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VPMAXNM2_I]] |
| // |
| float16x8_t test_vpmaxnmq_f16(float16x8_t a, float16x8_t b) { |
| return vpmaxnmq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpmin_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VPMIN2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fminp.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VPMIN2_I]] |
| // |
| float16x4_t test_vpmin_f16(float16x4_t a, float16x4_t b) { |
| return vpmin_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpminq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VPMIN2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fminp.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VPMIN2_I]] |
| // |
| float16x8_t test_vpminq_f16(float16x8_t a, float16x8_t b) { |
| return vpminq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpminnm_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VPMINNM2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fminnmp.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: ret <4 x half> [[VPMINNM2_I]] |
| // |
| float16x4_t test_vpminnm_f16(float16x4_t a, float16x4_t b) { |
| return vpminnm_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vpminnmq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VPMINNM2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fminnmp.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: ret <8 x half> [[VPMINNM2_I]] |
| // |
| float16x8_t test_vpminnmq_f16(float16x8_t a, float16x8_t b) { |
| return vpminnmq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrecps_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VRECPS_V2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.frecps.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: [[VRECPS_V3_I:%.*]] = bitcast <4 x half> [[VRECPS_V2_I]] to <8 x i8> |
| // CHECK-NEXT: ret <4 x half> [[VRECPS_V2_I]] |
| // |
| float16x4_t test_vrecps_f16(float16x4_t a, float16x4_t b) { |
| return vrecps_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrecpsq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VRECPSQ_V2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.frecps.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: [[VRECPSQ_V3_I:%.*]] = bitcast <8 x half> [[VRECPSQ_V2_I]] to <16 x i8> |
| // CHECK-NEXT: ret <8 x half> [[VRECPSQ_V2_I]] |
| // |
| float16x8_t test_vrecpsq_f16(float16x8_t a, float16x8_t b) { |
| return vrecpsq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrsqrts_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VRSQRTS_V2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.frsqrts.v4f16(<4 x half> [[A]], <4 x half> [[B]]) |
| // CHECK-NEXT: [[VRSQRTS_V3_I:%.*]] = bitcast <4 x half> [[VRSQRTS_V2_I]] to <8 x i8> |
| // CHECK-NEXT: ret <4 x half> [[VRSQRTS_V2_I]] |
| // |
| float16x4_t test_vrsqrts_f16(float16x4_t a, float16x4_t b) { |
| return vrsqrts_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrsqrtsq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VRSQRTSQ_V2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.frsqrts.v8f16(<8 x half> [[A]], <8 x half> [[B]]) |
| // CHECK-NEXT: [[VRSQRTSQ_V3_I:%.*]] = bitcast <8 x half> [[VRSQRTSQ_V2_I]] to <16 x i8> |
| // CHECK-NEXT: ret <8 x half> [[VRSQRTSQ_V2_I]] |
| // |
| float16x8_t test_vrsqrtsq_f16(float16x8_t a, float16x8_t b) { |
| return vrsqrtsq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vsub_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SUB_I:%.*]] = fsub <4 x half> [[A]], [[B]] |
| // CHECK-NEXT: ret <4 x half> [[SUB_I]] |
| // |
| float16x4_t test_vsub_f16(float16x4_t a, float16x4_t b) { |
| return vsub_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vsubq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SUB_I:%.*]] = fsub <8 x half> [[A]], [[B]] |
| // CHECK-NEXT: ret <8 x half> [[SUB_I]] |
| // |
| float16x8_t test_vsubq_f16(float16x8_t a, float16x8_t b) { |
| return vsubq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfma_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[C]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = call <4 x half> @llvm.fma.v4f16(<4 x half> [[B]], <4 x half> [[C]], <4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[TMP3]] |
| // |
| float16x4_t test_vfma_f16(float16x4_t a, float16x4_t b, float16x4_t c) { |
| return vfma_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[C]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[B]], <8 x half> [[C]], <8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[TMP3]] |
| // |
| float16x8_t test_vfmaq_f16(float16x8_t a, float16x8_t b, float16x8_t c) { |
| return vfmaq_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfms_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <4 x half> [[B]] |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[FNEG_I]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[C]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = call <4 x half> @llvm.fma.v4f16(<4 x half> [[FNEG_I]], <4 x half> [[C]], <4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[TMP3]] |
| // |
| float16x4_t test_vfms_f16(float16x4_t a, float16x4_t b, float16x4_t c) { |
| return vfms_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmsq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <8 x half> [[B]] |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[FNEG_I]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[C]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[FNEG_I]], <8 x half> [[C]], <8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[TMP3]] |
| // |
| float16x8_t test_vfmsq_f16(float16x8_t a, float16x8_t b, float16x8_t c) { |
| return vfmsq_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfma_lane_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[C]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP2]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP3]], <4 x half> [[TMP3]], <4 x i32> <i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: [[FMLA:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half> |
| // CHECK-NEXT: [[FMLA1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[FMLA2:%.*]] = call <4 x half> @llvm.fma.v4f16(<4 x half> [[FMLA]], <4 x half> [[LANE]], <4 x half> [[FMLA1]]) |
| // CHECK-NEXT: ret <4 x half> [[FMLA2]] |
| // |
| float16x4_t test_vfma_lane_f16(float16x4_t a, float16x4_t b, float16x4_t c) { |
| return vfma_lane_f16(a, b, c, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_lane_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[C]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP2]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP3]], <4 x half> [[TMP3]], <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: [[FMLA:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x half> |
| // CHECK-NEXT: [[FMLA1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[FMLA2:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[FMLA]], <8 x half> [[LANE]], <8 x half> [[FMLA1]]) |
| // CHECK-NEXT: ret <8 x half> [[FMLA2]] |
| // |
| float16x8_t test_vfmaq_lane_f16(float16x8_t a, float16x8_t b, float16x4_t c) { |
| return vfmaq_lane_f16(a, b, c, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfma_laneq_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[C]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half> |
| // CHECK-NEXT: [[TMP5:%.*]] = bitcast <16 x i8> [[TMP2]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP5]], <8 x half> [[TMP5]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> |
| // CHECK-NEXT: [[TMP6:%.*]] = call <4 x half> @llvm.fma.v4f16(<4 x half> [[LANE]], <4 x half> [[TMP4]], <4 x half> [[TMP3]]) |
| // CHECK-NEXT: ret <4 x half> [[TMP6]] |
| // |
| float16x4_t test_vfma_laneq_f16(float16x4_t a, float16x4_t b, float16x8_t c) { |
| return vfma_laneq_f16(a, b, c, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_laneq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[C]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x half> |
| // CHECK-NEXT: [[TMP5:%.*]] = bitcast <16 x i8> [[TMP2]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP5]], <8 x half> [[TMP5]], <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7> |
| // CHECK-NEXT: [[TMP6:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[LANE]], <8 x half> [[TMP4]], <8 x half> [[TMP3]]) |
| // CHECK-NEXT: ret <8 x half> [[TMP6]] |
| // |
| float16x8_t test_vfmaq_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c) { |
| return vfmaq_laneq_f16(a, b, c, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfma_n_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[C]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[C]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[C]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[C]], i32 3 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[VECINIT3]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = call <4 x half> @llvm.fma.v4f16(<4 x half> [[B]], <4 x half> [[VECINIT3]], <4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[TMP3]] |
| // |
| float16x4_t test_vfma_n_f16(float16x4_t a, float16x4_t b, float16_t c) { |
| return vfma_n_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_n_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[C]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[C]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[C]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[C]], i32 3 |
| // CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <8 x half> [[VECINIT3]], half [[C]], i32 4 |
| // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x half> [[VECINIT4]], half [[C]], i32 5 |
| // CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <8 x half> [[VECINIT5]], half [[C]], i32 6 |
| // CHECK-NEXT: [[VECINIT7:%.*]] = insertelement <8 x half> [[VECINIT6]], half [[C]], i32 7 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[VECINIT7]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[B]], <8 x half> [[VECINIT7]], <8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[TMP3]] |
| // |
| float16x8_t test_vfmaq_n_f16(float16x8_t a, float16x8_t b, float16_t c) { |
| return vfmaq_n_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmah_lane_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x half> [[C]], i32 3 |
| // CHECK-NEXT: [[TMP0:%.*]] = call half @llvm.fma.f16(half [[B]], half [[EXTRACT]], half [[A]]) |
| // CHECK-NEXT: ret half [[TMP0]] |
| // |
| float16_t test_vfmah_lane_f16(float16_t a, float16_t b, float16x4_t c) { |
| return vfmah_lane_f16(a, b, c, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmah_laneq_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <8 x half> [[C]], i32 7 |
| // CHECK-NEXT: [[TMP0:%.*]] = call half @llvm.fma.f16(half [[B]], half [[EXTRACT]], half [[A]]) |
| // CHECK-NEXT: ret half [[TMP0]] |
| // |
| float16_t test_vfmah_laneq_f16(float16_t a, float16_t b, float16x8_t c) { |
| return vfmah_laneq_f16(a, b, c, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfms_lane_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg <4 x half> [[B]] |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[FNEG]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[C]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP2]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP3]], <4 x half> [[TMP3]], <4 x i32> <i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: [[FMLA:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half> |
| // CHECK-NEXT: [[FMLA1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[FMLA2:%.*]] = call <4 x half> @llvm.fma.v4f16(<4 x half> [[FMLA]], <4 x half> [[LANE]], <4 x half> [[FMLA1]]) |
| // CHECK-NEXT: ret <4 x half> [[FMLA2]] |
| // |
| float16x4_t test_vfms_lane_f16(float16x4_t a, float16x4_t b, float16x4_t c) { |
| return vfms_lane_f16(a, b, c, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmsq_lane_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg <8 x half> [[B]] |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[FNEG]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[C]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP2]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP3]], <4 x half> [[TMP3]], <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: [[FMLA:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x half> |
| // CHECK-NEXT: [[FMLA1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[FMLA2:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[FMLA]], <8 x half> [[LANE]], <8 x half> [[FMLA1]]) |
| // CHECK-NEXT: ret <8 x half> [[FMLA2]] |
| // |
| float16x8_t test_vfmsq_lane_f16(float16x8_t a, float16x8_t b, float16x4_t c) { |
| return vfmsq_lane_f16(a, b, c, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfms_laneq_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg <4 x half> [[B]] |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[FNEG]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[C]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half> |
| // CHECK-NEXT: [[TMP5:%.*]] = bitcast <16 x i8> [[TMP2]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP5]], <8 x half> [[TMP5]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> |
| // CHECK-NEXT: [[TMP6:%.*]] = call <4 x half> @llvm.fma.v4f16(<4 x half> [[LANE]], <4 x half> [[TMP4]], <4 x half> [[TMP3]]) |
| // CHECK-NEXT: ret <4 x half> [[TMP6]] |
| // |
| float16x4_t test_vfms_laneq_f16(float16x4_t a, float16x4_t b, float16x8_t c) { |
| return vfms_laneq_f16(a, b, c, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmsq_laneq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg <8 x half> [[B]] |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[FNEG]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[C]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x half> |
| // CHECK-NEXT: [[TMP5:%.*]] = bitcast <16 x i8> [[TMP2]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP5]], <8 x half> [[TMP5]], <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7> |
| // CHECK-NEXT: [[TMP6:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[LANE]], <8 x half> [[TMP4]], <8 x half> [[TMP3]]) |
| // CHECK-NEXT: ret <8 x half> [[TMP6]] |
| // |
| float16x8_t test_vfmsq_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c) { |
| return vfmsq_laneq_f16(a, b, c, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfms_n_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg <4 x half> [[B]] |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[C]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[C]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[C]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[C]], i32 3 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[FNEG]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[VECINIT3]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = call <4 x half> @llvm.fma.v4f16(<4 x half> [[FNEG]], <4 x half> [[VECINIT3]], <4 x half> [[A]]) |
| // CHECK-NEXT: ret <4 x half> [[TMP3]] |
| // |
| float16x4_t test_vfms_n_f16(float16x4_t a, float16x4_t b, float16_t c) { |
| return vfms_n_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmsq_n_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg <8 x half> [[B]] |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[C]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[C]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[C]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[C]], i32 3 |
| // CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <8 x half> [[VECINIT3]], half [[C]], i32 4 |
| // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x half> [[VECINIT4]], half [[C]], i32 5 |
| // CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <8 x half> [[VECINIT5]], half [[C]], i32 6 |
| // CHECK-NEXT: [[VECINIT7:%.*]] = insertelement <8 x half> [[VECINIT6]], half [[C]], i32 7 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[FNEG]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[VECINIT7]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[FNEG]], <8 x half> [[VECINIT7]], <8 x half> [[A]]) |
| // CHECK-NEXT: ret <8 x half> [[TMP3]] |
| // |
| float16x8_t test_vfmsq_n_f16(float16x8_t a, float16x8_t b, float16_t c) { |
| return vfmsq_n_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmsh_lane_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CONV:%.*]] = fpext half [[B]] to float |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg float [[CONV]] |
| // CHECK-NEXT: [[TMP0:%.*]] = fptrunc float [[FNEG]] to half |
| // CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x half> [[C]], i32 3 |
| // CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fma.f16(half [[TMP0]], half [[EXTRACT]], half [[A]]) |
| // CHECK-NEXT: ret half [[TMP1]] |
| // |
| float16_t test_vfmsh_lane_f16(float16_t a, float16_t b, float16x4_t c) { |
| return vfmsh_lane_f16(a, b, c, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vfmsh_laneq_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CONV:%.*]] = fpext half [[B]] to float |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg float [[CONV]] |
| // CHECK-NEXT: [[TMP0:%.*]] = fptrunc float [[FNEG]] to half |
| // CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <8 x half> [[C]], i32 7 |
| // CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fma.f16(half [[TMP0]], half [[EXTRACT]], half [[A]]) |
| // CHECK-NEXT: ret half [[TMP1]] |
| // |
| float16_t test_vfmsh_laneq_f16(float16_t a, float16_t b, float16x8_t c) { |
| return vfmsh_laneq_f16(a, b, c, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmul_lane_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP1]], <4 x half> [[TMP1]], <4 x i32> <i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: [[MUL:%.*]] = fmul <4 x half> [[A]], [[LANE]] |
| // CHECK-NEXT: ret <4 x half> [[MUL]] |
| // |
| float16x4_t test_vmul_lane_f16(float16x4_t a, float16x4_t b) { |
| return vmul_lane_f16(a, b, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulq_lane_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP1]], <4 x half> [[TMP1]], <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: [[MUL:%.*]] = fmul <8 x half> [[A]], [[LANE]] |
| // CHECK-NEXT: ret <8 x half> [[MUL]] |
| // |
| float16x8_t test_vmulq_lane_f16(float16x8_t a, float16x4_t b) { |
| return vmulq_lane_f16(a, b, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmul_laneq_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP1]], <8 x half> [[TMP1]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> |
| // CHECK-NEXT: [[MUL:%.*]] = fmul <4 x half> [[A]], [[LANE]] |
| // CHECK-NEXT: ret <4 x half> [[MUL]] |
| // |
| float16x4_t test_vmul_laneq_f16(float16x4_t a, float16x8_t b) { |
| return vmul_laneq_f16(a, b, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulq_laneq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP1]], <8 x half> [[TMP1]], <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7> |
| // CHECK-NEXT: [[MUL:%.*]] = fmul <8 x half> [[A]], [[LANE]] |
| // CHECK-NEXT: ret <8 x half> [[MUL]] |
| // |
| float16x8_t test_vmulq_laneq_f16(float16x8_t a, float16x8_t b) { |
| return vmulq_laneq_f16(a, b, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmul_n_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[B]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[B]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[B]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[B]], i32 3 |
| // CHECK-NEXT: [[MUL:%.*]] = fmul <4 x half> [[A]], [[VECINIT3]] |
| // CHECK-NEXT: ret <4 x half> [[MUL]] |
| // |
| float16x4_t test_vmul_n_f16(float16x4_t a, float16_t b) { |
| return vmul_n_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulq_n_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[B]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[B]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[B]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[B]], i32 3 |
| // CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <8 x half> [[VECINIT3]], half [[B]], i32 4 |
| // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x half> [[VECINIT4]], half [[B]], i32 5 |
| // CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <8 x half> [[VECINIT5]], half [[B]], i32 6 |
| // CHECK-NEXT: [[VECINIT7:%.*]] = insertelement <8 x half> [[VECINIT6]], half [[B]], i32 7 |
| // CHECK-NEXT: [[MUL:%.*]] = fmul <8 x half> [[A]], [[VECINIT7]] |
| // CHECK-NEXT: ret <8 x half> [[MUL]] |
| // |
| float16x8_t test_vmulq_n_f16(float16x8_t a, float16_t b) { |
| return vmulq_n_f16(a, b); |
| } |
| |
| // FIXME: Fix it when fp16 non-storage-only type becomes available. |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulh_lane_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[__REINT_847:%.*]] = alloca <4 x half>, align 8 |
| // CHECK-NEXT: [[__REINT1_847:%.*]] = alloca i16, align 2 |
| // CHECK-NEXT: [[CONV:%.*]] = fpext half [[A]] to float |
| // CHECK-NEXT: store <4 x half> [[B]], ptr [[__REINT_847]], align 8 |
| // CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[__REINT_847]], align 8 |
| // CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP0]], i32 3 |
| // CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_847]], align 2 |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_847]], align 2 |
| // CHECK-NEXT: [[CONV2:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[MUL:%.*]] = fmul float [[CONV]], [[CONV2]] |
| // CHECK-NEXT: [[TMP2:%.*]] = fptrunc float [[MUL]] to half |
| // CHECK-NEXT: ret half [[TMP2]] |
| // |
| float16_t test_vmulh_lane_f16(float16_t a, float16x4_t b) { |
| return vmulh_lane_f16(a, b, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulh_laneq_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 |
| // CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 |
| // CHECK-NEXT: [[CONV:%.*]] = fpext half [[A]] to float |
| // CHECK-NEXT: store <8 x half> [[B]], ptr [[__REINT_850]], align 16 |
| // CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, ptr [[__REINT_850]], align 16 |
| // CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP0]], i32 7 |
| // CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_850]], align 2 |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_850]], align 2 |
| // CHECK-NEXT: [[CONV2:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[MUL:%.*]] = fmul float [[CONV]], [[CONV2]] |
| // CHECK-NEXT: [[TMP2:%.*]] = fptrunc float [[MUL]] to half |
| // CHECK-NEXT: ret half [[TMP2]] |
| // |
| float16_t test_vmulh_laneq_f16(float16_t a, float16x8_t b) { |
| return vmulh_laneq_f16(a, b, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulx_lane_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP1]], <4 x half> [[TMP1]], <4 x i32> <i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x half> [[LANE]] to <8 x i8> |
| // CHECK-NEXT: [[VMULX2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fmulx.v4f16(<4 x half> [[A]], <4 x half> [[LANE]]) |
| // CHECK-NEXT: ret <4 x half> [[VMULX2_I]] |
| // |
| float16x4_t test_vmulx_lane_f16(float16x4_t a, float16x4_t b) { |
| return vmulx_lane_f16(a, b, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulxq_lane_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP1]], <4 x half> [[TMP1]], <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x half> [[LANE]] to <16 x i8> |
| // CHECK-NEXT: [[VMULX2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fmulx.v8f16(<8 x half> [[A]], <8 x half> [[LANE]]) |
| // CHECK-NEXT: ret <8 x half> [[VMULX2_I]] |
| // |
| float16x8_t test_vmulxq_lane_f16(float16x8_t a, float16x4_t b) { |
| return vmulxq_lane_f16(a, b, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulx_laneq_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP1]], <8 x half> [[TMP1]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x half> [[LANE]] to <8 x i8> |
| // CHECK-NEXT: [[VMULX2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fmulx.v4f16(<4 x half> [[A]], <4 x half> [[LANE]]) |
| // CHECK-NEXT: ret <4 x half> [[VMULX2_I]] |
| // |
| float16x4_t test_vmulx_laneq_f16(float16x4_t a, float16x8_t b) { |
| return vmulx_laneq_f16(a, b, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulxq_laneq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP1]], <8 x half> [[TMP1]], <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x half> [[LANE]] to <16 x i8> |
| // CHECK-NEXT: [[VMULX2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fmulx.v8f16(<8 x half> [[A]], <8 x half> [[LANE]]) |
| // CHECK-NEXT: ret <8 x half> [[VMULX2_I]] |
| // |
| float16x8_t test_vmulxq_laneq_f16(float16x8_t a, float16x8_t b) { |
| return vmulxq_laneq_f16(a, b, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulx_n_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[B]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[B]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[B]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[B]], i32 3 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[VECINIT3]] to <8 x i8> |
| // CHECK-NEXT: [[VMULX2_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fmulx.v4f16(<4 x half> [[A]], <4 x half> [[VECINIT3]]) |
| // CHECK-NEXT: ret <4 x half> [[VMULX2_I]] |
| // |
| float16x4_t test_vmulx_n_f16(float16x4_t a, float16_t b) { |
| return vmulx_n_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulxq_n_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[B]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[B]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[B]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[B]], i32 3 |
| // CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <8 x half> [[VECINIT3]], half [[B]], i32 4 |
| // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x half> [[VECINIT4]], half [[B]], i32 5 |
| // CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <8 x half> [[VECINIT5]], half [[B]], i32 6 |
| // CHECK-NEXT: [[VECINIT7:%.*]] = insertelement <8 x half> [[VECINIT6]], half [[B]], i32 7 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[VECINIT7]] to <16 x i8> |
| // CHECK-NEXT: [[VMULX2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fmulx.v8f16(<8 x half> [[A]], <8 x half> [[VECINIT7]]) |
| // CHECK-NEXT: ret <8 x half> [[VMULX2_I]] |
| // |
| float16x8_t test_vmulxq_n_f16(float16x8_t a, float16_t b) { |
| return vmulxq_n_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulxh_lane_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x half> [[B]], i32 3 |
| // CHECK-NEXT: [[VMULX:%.*]] = call half @llvm.aarch64.neon.fmulx.f16(half [[A]], half [[EXTRACT]]) |
| // CHECK-NEXT: ret half [[VMULX]] |
| // |
| float16_t test_vmulxh_lane_f16(float16_t a, float16x4_t b) { |
| return vmulxh_lane_f16(a, b, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmulxh_laneq_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <8 x half> [[B]], i32 7 |
| // CHECK-NEXT: [[VMULX:%.*]] = call half @llvm.aarch64.neon.fmulx.f16(half [[A]], half [[EXTRACT]]) |
| // CHECK-NEXT: ret half [[VMULX]] |
| // |
| float16_t test_vmulxh_laneq_f16(float16_t a, float16x8_t b) { |
| return vmulxh_laneq_f16(a, b, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmaxv_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VMAXV:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[VMAXV1:%.*]] = call half @llvm.aarch64.neon.fmaxv.f16.v4f16(<4 x half> [[VMAXV]]) |
| // CHECK-NEXT: ret half [[VMAXV1]] |
| // |
| float16_t test_vmaxv_f16(float16x4_t a) { |
| return vmaxv_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmaxvq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VMAXV:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[VMAXV1:%.*]] = call half @llvm.aarch64.neon.fmaxv.f16.v8f16(<8 x half> [[VMAXV]]) |
| // CHECK-NEXT: ret half [[VMAXV1]] |
| // |
| float16_t test_vmaxvq_f16(float16x8_t a) { |
| return vmaxvq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vminv_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VMINV:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[VMINV1:%.*]] = call half @llvm.aarch64.neon.fminv.f16.v4f16(<4 x half> [[VMINV]]) |
| // CHECK-NEXT: ret half [[VMINV1]] |
| // |
| float16_t test_vminv_f16(float16x4_t a) { |
| return vminv_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vminvq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VMINV:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[VMINV1:%.*]] = call half @llvm.aarch64.neon.fminv.f16.v8f16(<8 x half> [[VMINV]]) |
| // CHECK-NEXT: ret half [[VMINV1]] |
| // |
| float16_t test_vminvq_f16(float16x8_t a) { |
| return vminvq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmaxnmv_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VMAXNMV:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[VMAXNMV1:%.*]] = call half @llvm.aarch64.neon.fmaxnmv.f16.v4f16(<4 x half> [[VMAXNMV]]) |
| // CHECK-NEXT: ret half [[VMAXNMV1]] |
| // |
| float16_t test_vmaxnmv_f16(float16x4_t a) { |
| return vmaxnmv_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmaxnmvq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VMAXNMV:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[VMAXNMV1:%.*]] = call half @llvm.aarch64.neon.fmaxnmv.f16.v8f16(<8 x half> [[VMAXNMV]]) |
| // CHECK-NEXT: ret half [[VMAXNMV1]] |
| // |
| float16_t test_vmaxnmvq_f16(float16x8_t a) { |
| return vmaxnmvq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vminnmv_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[VMINNMV:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[VMINNMV1:%.*]] = call half @llvm.aarch64.neon.fminnmv.f16.v4f16(<4 x half> [[VMINNMV]]) |
| // CHECK-NEXT: ret half [[VMINNMV1]] |
| // |
| float16_t test_vminnmv_f16(float16x4_t a) { |
| return vminnmv_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vminnmvq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[VMINNMV:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[VMINNMV1:%.*]] = call half @llvm.aarch64.neon.fminnmv.f16.v8f16(<8 x half> [[VMINNMV]]) |
| // CHECK-NEXT: ret half [[VMINNMV1]] |
| // |
| float16_t test_vminnmvq_f16(float16x8_t a) { |
| return vminnmvq_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vbsl_f16 |
| // CHECK-SAME: (<4 x i16> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x half> [[C]] to <8 x i8> |
| // CHECK-NEXT: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16> |
| // CHECK-NEXT: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <4 x i16> |
| // CHECK-NEXT: [[VBSL3_I:%.*]] = and <4 x i16> [[A]], [[VBSL1_I]] |
| // CHECK-NEXT: [[TMP3:%.*]] = xor <4 x i16> [[A]], <i16 -1, i16 -1, i16 -1, i16 -1> |
| // CHECK-NEXT: [[VBSL4_I:%.*]] = and <4 x i16> [[TMP3]], [[VBSL2_I]] |
| // CHECK-NEXT: [[VBSL5_I:%.*]] = or <4 x i16> [[VBSL3_I]], [[VBSL4_I]] |
| // CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i16> [[VBSL5_I]] to <4 x half> |
| // CHECK-NEXT: ret <4 x half> [[TMP4]] |
| // |
| float16x4_t test_vbsl_f16(uint16x4_t a, float16x4_t b, float16x4_t c) { |
| return vbsl_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vbslq_f16 |
| // CHECK-SAME: (<8 x i16> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[C]] to <16 x i8> |
| // CHECK-NEXT: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16> |
| // CHECK-NEXT: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <8 x i16> |
| // CHECK-NEXT: [[VBSL3_I:%.*]] = and <8 x i16> [[A]], [[VBSL1_I]] |
| // CHECK-NEXT: [[TMP3:%.*]] = xor <8 x i16> [[A]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> |
| // CHECK-NEXT: [[VBSL4_I:%.*]] = and <8 x i16> [[TMP3]], [[VBSL2_I]] |
| // CHECK-NEXT: [[VBSL5_I:%.*]] = or <8 x i16> [[VBSL3_I]], [[VBSL4_I]] |
| // CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[VBSL5_I]] to <8 x half> |
| // CHECK-NEXT: ret <8 x half> [[TMP4]] |
| // |
| float16x8_t test_vbslq_f16(uint16x8_t a, float16x8_t b, float16x8_t c) { |
| return vbslq_f16(a, b, c); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vzip_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RETVAL_I:%.*]] = alloca [[STRUCT_FLOAT16X4X2_T:%.*]], align 8 |
| // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FLOAT16X4X2_T]], align 8 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VZIP_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 0, i32 4, i32 1, i32 5> |
| // CHECK-NEXT: store <4 x half> [[VZIP_I]], ptr [[RETVAL_I]], align 8 |
| // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <4 x half>, ptr [[RETVAL_I]], i32 1 |
| // CHECK-NEXT: [[VZIP1_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 2, i32 6, i32 3, i32 7> |
| // CHECK-NEXT: store <4 x half> [[VZIP1_I]], ptr [[TMP2]], align 8 |
| // CHECK-NEXT: [[TMP3:%.*]] = load [[STRUCT_FLOAT16X4X2_T]], ptr [[RETVAL_I]], align 8 |
| // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_FLOAT16X4X2_T]], ptr [[RETVAL]], i32 0, i32 0 |
| // CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[STRUCT_FLOAT16X4X2_T]] [[TMP3]], 0 |
| // CHECK-NEXT: store [2 x <4 x half>] [[TMP5]], ptr [[TMP4]], align 8 |
| // CHECK-NEXT: [[TMP6:%.*]] = load [[STRUCT_FLOAT16X4X2_T]], ptr [[RETVAL]], align 8 |
| // CHECK-NEXT: ret [[STRUCT_FLOAT16X4X2_T]] [[TMP6]] |
| // |
| float16x4x2_t test_vzip_f16(float16x4_t a, float16x4_t b) { |
| return vzip_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vzipq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RETVAL_I:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T:%.*]], align 16 |
| // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T]], align 16 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VZIP_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11> |
| // CHECK-NEXT: store <8 x half> [[VZIP_I]], ptr [[RETVAL_I]], align 16 |
| // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <8 x half>, ptr [[RETVAL_I]], i32 1 |
| // CHECK-NEXT: [[VZIP1_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15> |
| // CHECK-NEXT: store <8 x half> [[VZIP1_I]], ptr [[TMP2]], align 16 |
| // CHECK-NEXT: [[TMP3:%.*]] = load [[STRUCT_FLOAT16X8X2_T]], ptr [[RETVAL_I]], align 16 |
| // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_FLOAT16X8X2_T]], ptr [[RETVAL]], i32 0, i32 0 |
| // CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[STRUCT_FLOAT16X8X2_T]] [[TMP3]], 0 |
| // CHECK-NEXT: store [2 x <8 x half>] [[TMP5]], ptr [[TMP4]], align 16 |
| // CHECK-NEXT: [[TMP6:%.*]] = load [[STRUCT_FLOAT16X8X2_T]], ptr [[RETVAL]], align 16 |
| // CHECK-NEXT: ret [[STRUCT_FLOAT16X8X2_T]] [[TMP6]] |
| // |
| float16x8x2_t test_vzipq_f16(float16x8_t a, float16x8_t b) { |
| return vzipq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vuzp_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RETVAL_I:%.*]] = alloca [[STRUCT_FLOAT16X4X2_T:%.*]], align 8 |
| // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FLOAT16X4X2_T]], align 8 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VUZP_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 0, i32 2, i32 4, i32 6> |
| // CHECK-NEXT: store <4 x half> [[VUZP_I]], ptr [[RETVAL_I]], align 8 |
| // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <4 x half>, ptr [[RETVAL_I]], i32 1 |
| // CHECK-NEXT: [[VUZP1_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| // CHECK-NEXT: store <4 x half> [[VUZP1_I]], ptr [[TMP2]], align 8 |
| // CHECK-NEXT: [[TMP3:%.*]] = load [[STRUCT_FLOAT16X4X2_T]], ptr [[RETVAL_I]], align 8 |
| // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_FLOAT16X4X2_T]], ptr [[RETVAL]], i32 0, i32 0 |
| // CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[STRUCT_FLOAT16X4X2_T]] [[TMP3]], 0 |
| // CHECK-NEXT: store [2 x <4 x half>] [[TMP5]], ptr [[TMP4]], align 8 |
| // CHECK-NEXT: [[TMP6:%.*]] = load [[STRUCT_FLOAT16X4X2_T]], ptr [[RETVAL]], align 8 |
| // CHECK-NEXT: ret [[STRUCT_FLOAT16X4X2_T]] [[TMP6]] |
| // |
| float16x4x2_t test_vuzp_f16(float16x4_t a, float16x4_t b) { |
| return vuzp_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vuzpq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RETVAL_I:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T:%.*]], align 16 |
| // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T]], align 16 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VUZP_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14> |
| // CHECK-NEXT: store <8 x half> [[VUZP_I]], ptr [[RETVAL_I]], align 16 |
| // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <8 x half>, ptr [[RETVAL_I]], i32 1 |
| // CHECK-NEXT: [[VUZP1_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15> |
| // CHECK-NEXT: store <8 x half> [[VUZP1_I]], ptr [[TMP2]], align 16 |
| // CHECK-NEXT: [[TMP3:%.*]] = load [[STRUCT_FLOAT16X8X2_T]], ptr [[RETVAL_I]], align 16 |
| // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_FLOAT16X8X2_T]], ptr [[RETVAL]], i32 0, i32 0 |
| // CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[STRUCT_FLOAT16X8X2_T]] [[TMP3]], 0 |
| // CHECK-NEXT: store [2 x <8 x half>] [[TMP5]], ptr [[TMP4]], align 16 |
| // CHECK-NEXT: [[TMP6:%.*]] = load [[STRUCT_FLOAT16X8X2_T]], ptr [[RETVAL]], align 16 |
| // CHECK-NEXT: ret [[STRUCT_FLOAT16X8X2_T]] [[TMP6]] |
| // |
| float16x8x2_t test_vuzpq_f16(float16x8_t a, float16x8_t b) { |
| return vuzpq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vtrn_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RETVAL_I:%.*]] = alloca [[STRUCT_FLOAT16X4X2_T:%.*]], align 8 |
| // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FLOAT16X4X2_T]], align 8 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[VTRN_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 0, i32 4, i32 2, i32 6> |
| // CHECK-NEXT: store <4 x half> [[VTRN_I]], ptr [[RETVAL_I]], align 8 |
| // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <4 x half>, ptr [[RETVAL_I]], i32 1 |
| // CHECK-NEXT: [[VTRN1_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 1, i32 5, i32 3, i32 7> |
| // CHECK-NEXT: store <4 x half> [[VTRN1_I]], ptr [[TMP2]], align 8 |
| // CHECK-NEXT: [[TMP3:%.*]] = load [[STRUCT_FLOAT16X4X2_T]], ptr [[RETVAL_I]], align 8 |
| // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_FLOAT16X4X2_T]], ptr [[RETVAL]], i32 0, i32 0 |
| // CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[STRUCT_FLOAT16X4X2_T]] [[TMP3]], 0 |
| // CHECK-NEXT: store [2 x <4 x half>] [[TMP5]], ptr [[TMP4]], align 8 |
| // CHECK-NEXT: [[TMP6:%.*]] = load [[STRUCT_FLOAT16X4X2_T]], ptr [[RETVAL]], align 8 |
| // CHECK-NEXT: ret [[STRUCT_FLOAT16X4X2_T]] [[TMP6]] |
| // |
| float16x4x2_t test_vtrn_f16(float16x4_t a, float16x4_t b) { |
| return vtrn_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vtrnq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RETVAL_I:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T:%.*]], align 16 |
| // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T]], align 16 |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[VTRN_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14> |
| // CHECK-NEXT: store <8 x half> [[VTRN_I]], ptr [[RETVAL_I]], align 16 |
| // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <8 x half>, ptr [[RETVAL_I]], i32 1 |
| // CHECK-NEXT: [[VTRN1_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15> |
| // CHECK-NEXT: store <8 x half> [[VTRN1_I]], ptr [[TMP2]], align 16 |
| // CHECK-NEXT: [[TMP3:%.*]] = load [[STRUCT_FLOAT16X8X2_T]], ptr [[RETVAL_I]], align 16 |
| // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_FLOAT16X8X2_T]], ptr [[RETVAL]], i32 0, i32 0 |
| // CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[STRUCT_FLOAT16X8X2_T]] [[TMP3]], 0 |
| // CHECK-NEXT: store [2 x <8 x half>] [[TMP5]], ptr [[TMP4]], align 16 |
| // CHECK-NEXT: [[TMP6:%.*]] = load [[STRUCT_FLOAT16X8X2_T]], ptr [[RETVAL]], align 16 |
| // CHECK-NEXT: ret [[STRUCT_FLOAT16X8X2_T]] [[TMP6]] |
| // |
| float16x8x2_t test_vtrnq_f16(float16x8_t a, float16x8_t b) { |
| return vtrnq_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmov_n_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[A]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[A]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[A]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[A]], i32 3 |
| // CHECK-NEXT: ret <4 x half> [[VECINIT3]] |
| // |
| float16x4_t test_vmov_n_f16(float16_t a) { |
| return vmov_n_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vmovq_n_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[A]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[A]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[A]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[A]], i32 3 |
| // CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <8 x half> [[VECINIT3]], half [[A]], i32 4 |
| // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x half> [[VECINIT4]], half [[A]], i32 5 |
| // CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <8 x half> [[VECINIT5]], half [[A]], i32 6 |
| // CHECK-NEXT: [[VECINIT7:%.*]] = insertelement <8 x half> [[VECINIT6]], half [[A]], i32 7 |
| // CHECK-NEXT: ret <8 x half> [[VECINIT7]] |
| // |
| float16x8_t test_vmovq_n_f16(float16_t a) { |
| return vmovq_n_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vdup_n_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[A]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[A]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[A]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[A]], i32 3 |
| // CHECK-NEXT: ret <4 x half> [[VECINIT3]] |
| // |
| float16x4_t test_vdup_n_f16(float16_t a) { |
| return vdup_n_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vdupq_n_f16 |
| // CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[A]], i32 0 |
| // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[A]], i32 1 |
| // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[A]], i32 2 |
| // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[A]], i32 3 |
| // CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <8 x half> [[VECINIT3]], half [[A]], i32 4 |
| // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x half> [[VECINIT4]], half [[A]], i32 5 |
| // CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <8 x half> [[VECINIT5]], half [[A]], i32 6 |
| // CHECK-NEXT: [[VECINIT7:%.*]] = insertelement <8 x half> [[VECINIT6]], half [[A]], i32 7 |
| // CHECK-NEXT: ret <8 x half> [[VECINIT7]] |
| // |
| float16x8_t test_vdupq_n_f16(float16_t a) { |
| return vdupq_n_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vdup_lane_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP1]], <4 x half> [[TMP1]], <4 x i32> <i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: ret <4 x half> [[LANE]] |
| // |
| float16x4_t test_vdup_lane_f16(float16x4_t a) { |
| return vdup_lane_f16(a, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vdupq_lane_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x half> [[TMP1]], <4 x half> [[TMP1]], <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> |
| // CHECK-NEXT: ret <8 x half> [[LANE]] |
| // |
| float16x8_t test_vdupq_lane_f16(float16x4_t a) { |
| return vdupq_lane_f16(a, 3); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vdup_laneq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP1]], <8 x half> [[TMP1]], <4 x i32> <i32 1, i32 1, i32 1, i32 1> |
| // CHECK-NEXT: ret <4 x half> [[LANE]] |
| // |
| float16x4_t test_vdup_laneq_f16(float16x8_t a) { |
| return vdup_laneq_f16(a, 1); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vdupq_laneq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[LANE:%.*]] = shufflevector <8 x half> [[TMP1]], <8 x half> [[TMP1]], <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7> |
| // CHECK-NEXT: ret <8 x half> [[LANE]] |
| // |
| float16x8_t test_vdupq_laneq_f16(float16x8_t a) { |
| return vdupq_laneq_f16(a, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vext_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half> |
| // CHECK-NEXT: [[VEXT:%.*]] = shufflevector <4 x half> [[TMP2]], <4 x half> [[TMP3]], <4 x i32> <i32 2, i32 3, i32 4, i32 5> |
| // CHECK-NEXT: ret <4 x half> [[VEXT]] |
| // |
| float16x4_t test_vext_f16(float16x4_t a, float16x4_t b) { |
| return vext_f16(a, b, 2); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vextq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> |
| // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> |
| // CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> |
| // CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x half> |
| // CHECK-NEXT: [[VEXT:%.*]] = shufflevector <8 x half> [[TMP2]], <8 x half> [[TMP3]], <8 x i32> <i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12> |
| // CHECK-NEXT: ret <8 x half> [[VEXT]] |
| // |
| float16x8_t test_vextq_f16(float16x8_t a, float16x8_t b) { |
| return vextq_f16(a, b, 5); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrev64_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[A]], <4 x i32> <i32 3, i32 2, i32 1, i32 0> |
| // CHECK-NEXT: ret <4 x half> [[SHUFFLE_I]] |
| // |
| float16x4_t test_vrev64_f16(float16x4_t a) { |
| return vrev64_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vrev64q_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[A]], <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4> |
| // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] |
| // |
| float16x8_t test_vrev64q_f16(float16x8_t a) { |
| return vrev64q_f16(a); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vzip1_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 0, i32 4, i32 1, i32 5> |
| // CHECK-NEXT: ret <4 x half> [[SHUFFLE_I]] |
| // |
| float16x4_t test_vzip1_f16(float16x4_t a, float16x4_t b) { |
| return vzip1_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vzip1q_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11> |
| // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] |
| // |
| float16x8_t test_vzip1q_f16(float16x8_t a, float16x8_t b) { |
| return vzip1q_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vzip2_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 2, i32 6, i32 3, i32 7> |
| // CHECK-NEXT: ret <4 x half> [[SHUFFLE_I]] |
| // |
| float16x4_t test_vzip2_f16(float16x4_t a, float16x4_t b) { |
| return vzip2_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vzip2q_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15> |
| // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] |
| // |
| float16x8_t test_vzip2q_f16(float16x8_t a, float16x8_t b) { |
| return vzip2q_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vuzp1_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 0, i32 2, i32 4, i32 6> |
| // CHECK-NEXT: ret <4 x half> [[SHUFFLE_I]] |
| // |
| float16x4_t test_vuzp1_f16(float16x4_t a, float16x4_t b) { |
| return vuzp1_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vuzp1q_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14> |
| // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] |
| // |
| float16x8_t test_vuzp1q_f16(float16x8_t a, float16x8_t b) { |
| return vuzp1q_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vuzp2_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| // CHECK-NEXT: ret <4 x half> [[SHUFFLE_I]] |
| // |
| float16x4_t test_vuzp2_f16(float16x4_t a, float16x4_t b) { |
| return vuzp2_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vuzp2q_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15> |
| // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] |
| // |
| float16x8_t test_vuzp2q_f16(float16x8_t a, float16x8_t b) { |
| return vuzp2q_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vtrn1_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 0, i32 4, i32 2, i32 6> |
| // CHECK-NEXT: ret <4 x half> [[SHUFFLE_I]] |
| // |
| float16x4_t test_vtrn1_f16(float16x4_t a, float16x4_t b) { |
| return vtrn1_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vtrn1q_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14> |
| // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] |
| // |
| float16x8_t test_vtrn1q_f16(float16x8_t a, float16x8_t b) { |
| return vtrn1q_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vtrn2_f16 |
| // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> [[B]], <4 x i32> <i32 1, i32 5, i32 3, i32 7> |
| // CHECK-NEXT: ret <4 x half> [[SHUFFLE_I]] |
| // |
| float16x4_t test_vtrn2_f16(float16x4_t a, float16x4_t b) { |
| return vtrn2_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vtrn2q_f16 |
| // CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15> |
| // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] |
| // |
| float16x8_t test_vtrn2q_f16(float16x8_t a, float16x8_t b) { |
| return vtrn2q_f16(a, b); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vduph_laneq_f16 |
| // CHECK-SAME: (<8 x half> noundef [[VEC:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x half> [[VEC]], i32 7 |
| // CHECK-NEXT: ret half [[VGETQ_LANE]] |
| // |
| float16_t test_vduph_laneq_f16(float16x8_t vec) { |
| return vduph_laneq_f16(vec, 7); |
| } |
| |
| // CHECK-LABEL: define {{[^@]+}}@test_vduph_lane_f16 |
| // CHECK-SAME: (<4 x half> noundef [[VEC:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x half> [[VEC]], i32 3 |
| // CHECK-NEXT: ret half [[VGET_LANE]] |
| // |
| float16_t test_vduph_lane_f16(float16x4_t vec) { |
| return vduph_lane_f16(vec, 3); |
| } |