299 lines · c
1// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +fullfp16 \2// RUN: -disable-O0-optnone \3// RUN: -emit-llvm -o - %s | opt -S -passes=mem2reg \4// RUN: | FileCheck --check-prefixes=COMMON,COMMONIR,UNCONSTRAINED %s5// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +fullfp16 \6// RUN: -disable-O0-optnone \7// RUN: -ffp-exception-behavior=strict -emit-llvm -o - %s | opt -S -passes=mem2reg \8// RUN: | FileCheck --check-prefixes=COMMON,COMMONIR,CONSTRAINED %s9 10// REQUIRES: aarch64-registered-target11 12#include <arm_fp16.h>13 14// COMMON-LABEL: test_vceqzh_f1615// UNCONSTRAINED: [[TMP1:%.*]] = fcmp oeq half %a, 0xH000016// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half 0xH0000, metadata !"oeq", metadata !"fpexcept.strict")17// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i1618// COMMONIR: ret i16 [[TMP2]]19uint16_t test_vceqzh_f16(float16_t a) {20 return vceqzh_f16(a);21}22 23// COMMON-LABEL: test_vcgezh_f1624// UNCONSTRAINED: [[TMP1:%.*]] = fcmp oge half %a, 0xH000025// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half 0xH0000, metadata !"oge", metadata !"fpexcept.strict")26// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i1627// COMMONIR: ret i16 [[TMP2]]28uint16_t test_vcgezh_f16(float16_t a) {29 return vcgezh_f16(a);30}31 32// COMMON-LABEL: test_vcgtzh_f1633// UNCONSTRAINED: [[TMP1:%.*]] = fcmp ogt half %a, 0xH000034// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half 0xH0000, metadata !"ogt", metadata !"fpexcept.strict")35// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i1636// COMMONIR: ret i16 [[TMP2]]37uint16_t test_vcgtzh_f16(float16_t a) {38 return vcgtzh_f16(a);39}40 41// COMMON-LABEL: test_vclezh_f1642// UNCONSTRAINED: [[TMP1:%.*]] = fcmp ole half %a, 0xH000043// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half 0xH0000, metadata !"ole", metadata !"fpexcept.strict")44// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i1645// COMMONIR: ret i16 [[TMP2]]46uint16_t test_vclezh_f16(float16_t a) {47 return vclezh_f16(a);48}49 50// COMMON-LABEL: test_vcltzh_f1651// UNCONSTRAINED: [[TMP1:%.*]] = fcmp olt half %a, 0xH000052// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half 0xH0000, metadata !"olt", metadata !"fpexcept.strict")53// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i1654// COMMONIR: ret i16 [[TMP2]]55uint16_t test_vcltzh_f16(float16_t a) {56 return vcltzh_f16(a);57}58 59// COMMON-LABEL: test_vcvth_f16_s1660// UNCONSTRAINED: [[VCVT:%.*]] = sitofp i16 %a to half61// CONSTRAINED: [[VCVT:%.*]] = call half @llvm.experimental.constrained.sitofp.f16.i16(i16 %a, metadata !"round.tonearest", metadata !"fpexcept.strict")62// COMMONIR: ret half [[VCVT]]63float16_t test_vcvth_f16_s16 (int16_t a) {64 return vcvth_f16_s16(a);65}66 67// COMMON-LABEL: test_vcvth_f16_s3268// UNCONSTRAINED: [[VCVT:%.*]] = sitofp i32 %a to half69// CONSTRAINED: [[VCVT:%.*]] = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict")70// COMMONIR: ret half [[VCVT]]71float16_t test_vcvth_f16_s32 (int32_t a) {72 return vcvth_f16_s32(a);73}74 75// COMMON-LABEL: test_vcvth_f16_s6476// UNCONSTRAINED: [[VCVT:%.*]] = sitofp i64 %a to half77// CONSTRAINED: [[VCVT:%.*]] = call half @llvm.experimental.constrained.sitofp.f16.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.strict")78// COMMONIR: ret half [[VCVT]]79float16_t test_vcvth_f16_s64 (int64_t a) {80 return vcvth_f16_s64(a);81}82 83// COMMON-LABEL: test_vcvth_f16_u1684// UNCONSTRAINED: [[VCVT:%.*]] = uitofp i16 %a to half85// CONSTRAINED: [[VCVT:%.*]] = call half @llvm.experimental.constrained.uitofp.f16.i16(i16 %a, metadata !"round.tonearest", metadata !"fpexcept.strict")86// COMMONIR: ret half [[VCVT]]87float16_t test_vcvth_f16_u16 (uint16_t a) {88 return vcvth_f16_u16(a);89}90 91// COMMON-LABEL: test_vcvth_f16_u3292// UNCONSTRAINED: [[VCVT:%.*]] = uitofp i32 %a to half93// CONSTRAINED: [[VCVT:%.*]] = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict")94// COMMONIR: ret half [[VCVT]]95float16_t test_vcvth_f16_u32 (uint32_t a) {96 return vcvth_f16_u32(a);97}98 99// COMMON-LABEL: test_vcvth_f16_u64100// UNCONSTRAINED: [[VCVT:%.*]] = uitofp i64 %a to half101// CONSTRAINED: [[VCVT:%.*]] = call half @llvm.experimental.constrained.uitofp.f16.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.strict")102// COMMONIR: ret half [[VCVT]]103float16_t test_vcvth_f16_u64 (uint64_t a) {104 return vcvth_f16_u64(a);105}106 107// COMMON-LABEL: test_vcvth_s16_f16108// COMMONIR: [[VCVT:%.*]] = call i16 @llvm.aarch64.neon.fcvtzs.i16.f16(half %a)109// COMMONIR: ret i16 [[VCVT]]110int16_t test_vcvth_s16_f16 (float16_t a) {111 return vcvth_s16_f16(a);112}113 114// COMMON-LABEL: test_vcvth_s32_f16115// COMMONIR: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtzs.i32.f16(half %a)116// COMMONIR: ret i32 [[VCVT]]117int32_t test_vcvth_s32_f16 (float16_t a) {118 return vcvth_s32_f16(a);119}120 121// COMMON-LABEL: test_vcvth_s64_f16122// COMMONIR: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtzs.i64.f16(half %a)123// COMMONIR: ret i64 [[VCVT]]124int64_t test_vcvth_s64_f16 (float16_t a) {125 return vcvth_s64_f16(a);126}127 128// COMMON-LABEL: test_vcvth_u16_f16129// COMMONIR: [[VCVT:%.*]] = call i16 @llvm.aarch64.neon.fcvtzu.i16.f16(half %a)130// COMMONIR: ret i16 [[VCVT]]131uint16_t test_vcvth_u16_f16 (float16_t a) {132 return vcvth_u16_f16(a);133}134 135// COMMON-LABEL: test_vcvth_u32_f16136// COMMONIR: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtzu.i32.f16(half %a)137// COMMONIR: ret i32 [[VCVT]]138uint32_t test_vcvth_u32_f16 (float16_t a) {139 return vcvth_u32_f16(a);140}141 142// COMMON-LABEL: test_vcvth_u64_f16143// COMMONIR: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtzu.i64.f16(half %a)144// COMMONIR: ret i64 [[VCVT]]145uint64_t test_vcvth_u64_f16 (float16_t a) {146 return vcvth_u64_f16(a);147}148 149// COMMON-LABEL: test_vrndh_f16150// UNCONSTRAINED: [[RND:%.*]] = call half @llvm.trunc.f16(half %a)151// CONSTRAINED: [[RND:%.*]] = call half @llvm.experimental.constrained.trunc.f16(half %a, metadata !"fpexcept.strict")152// COMMONIR: ret half [[RND]]153float16_t test_vrndh_f16(float16_t a) {154 return vrndh_f16(a);155}156 157// COMMON-LABEL: test_vrndah_f16158// UNCONSTRAINED: [[RND:%.*]] = call half @llvm.round.f16(half %a)159// CONSTRAINED: [[RND:%.*]] = call half @llvm.experimental.constrained.round.f16(half %a, metadata !"fpexcept.strict")160// COMMONIR: ret half [[RND]]161float16_t test_vrndah_f16(float16_t a) {162 return vrndah_f16(a);163}164 165// COMMON-LABEL: test_vrndih_f16166// UNCONSTRAINED: [[RND:%.*]] = call half @llvm.nearbyint.f16(half %a)167// CONSTRAINED: [[RND:%.*]] = call half @llvm.experimental.constrained.nearbyint.f16(half %a, metadata !"round.tonearest", metadata !"fpexcept.strict")168// COMMONIR: ret half [[RND]]169float16_t test_vrndih_f16(float16_t a) {170 return vrndih_f16(a);171}172 173// COMMON-LABEL: test_vrndmh_f16174// UNCONSTRAINED: [[RND:%.*]] = call half @llvm.floor.f16(half %a)175// CONSTRAINED: [[RND:%.*]] = call half @llvm.experimental.constrained.floor.f16(half %a, metadata !"fpexcept.strict")176// COMMONIR: ret half [[RND]]177float16_t test_vrndmh_f16(float16_t a) {178 return vrndmh_f16(a);179}180 181// COMMON-LABEL: test_vrndph_f16182// UNCONSTRAINED: [[RND:%.*]] = call half @llvm.ceil.f16(half %a)183// CONSTRAINED: [[RND:%.*]] = call half @llvm.experimental.constrained.ceil.f16(half %a, metadata !"fpexcept.strict")184// COMMONIR: ret half [[RND]]185float16_t test_vrndph_f16(float16_t a) {186 return vrndph_f16(a);187}188 189// COMMON-LABEL: test_vrndxh_f16190// UNCONSTRAINED: [[RND:%.*]] = call half @llvm.rint.f16(half %a)191// CONSTRAINED: [[RND:%.*]] = call half @llvm.experimental.constrained.rint.f16(half %a, metadata !"round.tonearest", metadata !"fpexcept.strict")192// COMMONIR: ret half [[RND]]193float16_t test_vrndxh_f16(float16_t a) {194 return vrndxh_f16(a);195}196 197// COMMON-LABEL: test_vsqrth_f16198// UNCONSTRAINED: [[SQR:%.*]] = call half @llvm.sqrt.f16(half %a)199// CONSTRAINED: [[SQR:%.*]] = call half @llvm.experimental.constrained.sqrt.f16(half %a, metadata !"round.tonearest", metadata !"fpexcept.strict")200// COMMONIR: ret half [[SQR]]201float16_t test_vsqrth_f16(float16_t a) {202 return vsqrth_f16(a);203}204 205// COMMON-LABEL: test_vaddh_f16206// UNCONSTRAINED: [[ADD:%.*]] = fadd half %a, %b207// CONSTRAINED: [[ADD:%.*]] = call half @llvm.experimental.constrained.fadd.f16(half %a, half %b, metadata !"round.tonearest", metadata !"fpexcept.strict")208// COMMONIR: ret half [[ADD]]209float16_t test_vaddh_f16(float16_t a, float16_t b) {210 return vaddh_f16(a, b);211}212 213// COMMON-LABEL: test_vceqh_f16214// UNCONSTRAINED: [[TMP1:%.*]] = fcmp oeq half %a, %b215// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"oeq", metadata !"fpexcept.strict")216// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i16217// COMMONIR: ret i16 [[TMP2]]218uint16_t test_vceqh_f16(float16_t a, float16_t b) {219 return vceqh_f16(a, b);220}221 222// COMMON-LABEL: test_vcgeh_f16223// UNCONSTRAINED: [[TMP1:%.*]] = fcmp oge half %a, %b224// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"oge", metadata !"fpexcept.strict")225// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i16226// COMMONIR: ret i16 [[TMP2]]227uint16_t test_vcgeh_f16(float16_t a, float16_t b) {228 return vcgeh_f16(a, b);229}230 231// COMMON-LABEL: test_vcgth_f16232// UNCONSTRAINED: [[TMP1:%.*]] = fcmp ogt half %a, %b233// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ogt", metadata !"fpexcept.strict")234// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i16235// COMMONIR: ret i16 [[TMP2]]236uint16_t test_vcgth_f16(float16_t a, float16_t b) {237 return vcgth_f16(a, b);238}239 240// COMMON-LABEL: test_vcleh_f16241// UNCONSTRAINED: [[TMP1:%.*]] = fcmp ole half %a, %b242// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict")243// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i16244// COMMONIR: ret i16 [[TMP2]]245uint16_t test_vcleh_f16(float16_t a, float16_t b) {246 return vcleh_f16(a, b);247}248 249// COMMON-LABEL: test_vclth_f16250// UNCONSTRAINED: [[TMP1:%.*]] = fcmp olt half %a, %b251// CONSTRAINED: [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict")252// COMMONIR: [[TMP2:%.*]] = sext i1 [[TMP1]] to i16253// COMMONIR: ret i16 [[TMP2]]254uint16_t test_vclth_f16(float16_t a, float16_t b) {255 return vclth_f16(a, b);256}257 258// COMMON-LABEL: test_vdivh_f16259// UNCONSTRAINED: [[DIV:%.*]] = fdiv half %a, %b260// CONSTRAINED: [[DIV:%.*]] = call half @llvm.experimental.constrained.fdiv.f16(half %a, half %b, metadata !"round.tonearest", metadata !"fpexcept.strict")261// COMMONIR: ret half [[DIV]]262float16_t test_vdivh_f16(float16_t a, float16_t b) {263 return vdivh_f16(a, b);264}265 266// COMMON-LABEL: test_vmulh_f16267// UNCONSTRAINED: [[MUL:%.*]] = fmul half %a, %b268// CONSTRAINED: [[MUL:%.*]] = call half @llvm.experimental.constrained.fmul.f16(half %a, half %b, metadata !"round.tonearest", metadata !"fpexcept.strict")269// COMMONIR: ret half [[MUL]]270float16_t test_vmulh_f16(float16_t a, float16_t b) {271 return vmulh_f16(a, b);272}273 274// COMMON-LABEL: test_vsubh_f16275// UNCONSTRAINED: [[SUB:%.*]] = fsub half %a, %b276// CONSTRAINED: [[SUB:%.*]] = call half @llvm.experimental.constrained.fsub.f16(half %a, half %b, metadata !"round.tonearest", metadata !"fpexcept.strict")277// COMMONIR: ret half [[SUB]]278float16_t test_vsubh_f16(float16_t a, float16_t b) {279 return vsubh_f16(a, b);280}281 282// COMMON-LABEL: test_vfmah_f16283// UNCONSTRAINED: [[FMA:%.*]] = call half @llvm.fma.f16(half %b, half %c, half %a)284// CONSTRAINED: [[FMA:%.*]] = call half @llvm.experimental.constrained.fma.f16(half %b, half %c, half %a, metadata !"round.tonearest", metadata !"fpexcept.strict")285// COMMONIR: ret half [[FMA]]286float16_t test_vfmah_f16(float16_t a, float16_t b, float16_t c) {287 return vfmah_f16(a, b, c);288}289 290// COMMON-LABEL: test_vfmsh_f16291// COMMONIR: [[SUB:%.*]] = fneg half %b292// UNCONSTRAINED: [[ADD:%.*]] = call half @llvm.fma.f16(half [[SUB]], half %c, half %a)293// CONSTRAINED: [[ADD:%.*]] = call half @llvm.experimental.constrained.fma.f16(half [[SUB]], half %c, half %a, metadata !"round.tonearest", metadata !"fpexcept.strict")294// COMMONIR: ret half [[ADD]]295float16_t test_vfmsh_f16(float16_t a, float16_t b, float16_t c) {296 return vfmsh_f16(a, b, c);297}298 299