| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc < %s -mtriple=x86_64-unknown-unknown --fp-contract=fast --enable-no-signed-zeros-fp-math -mattr=avx512fp16 | FileCheck %s --check-prefixes=CHECK,NO-SZ |
| ; RUN: llc < %s -mtriple=x86_64-unknown-unknown --fp-contract=fast -mattr=avx512fp16 | FileCheck %s --check-prefixes=CHECK,HAS-SZ |
| |
| ; FADD(acc, FMA(a, b, +0.0)) can be combined to FMA(a, b, acc) if the nsz flag set. |
| define dso_local <32 x half> @test1(<32 x half> %acc, <32 x half> %a, <32 x half> %b) { |
| ; NO-SZ-LABEL: test1: |
| ; NO-SZ: # %bb.0: # %entry |
| ; NO-SZ-NEXT: vfcmaddcph %zmm2, %zmm1, %zmm0 |
| ; NO-SZ-NEXT: retq |
| ; |
| ; HAS-SZ-LABEL: test1: |
| ; HAS-SZ: # %bb.0: # %entry |
| ; HAS-SZ-NEXT: vxorps %xmm3, %xmm3, %xmm3 |
| ; HAS-SZ-NEXT: vfcmaddcph %zmm2, %zmm1, %zmm3 |
| ; HAS-SZ-NEXT: vaddph %zmm0, %zmm3, %zmm0 |
| ; HAS-SZ-NEXT: retq |
| entry: |
| %0 = bitcast <32 x half> %a to <16 x float> |
| %1 = bitcast <32 x half> %b to <16 x float> |
| %2 = tail call <16 x float> @llvm.x86.avx512fp16.mask.vfcmadd.cph.512(<16 x float> %0, <16 x float> %1, <16 x float> zeroinitializer, i16 -1, i32 4) |
| %3 = bitcast <16 x float> %2 to <32 x half> |
| %add.i = fadd <32 x half> %3, %acc |
| ret <32 x half> %add.i |
| } |
| |
| define dso_local <32 x half> @test2(<32 x half> %acc, <32 x half> %a, <32 x half> %b) { |
| ; NO-SZ-LABEL: test2: |
| ; NO-SZ: # %bb.0: # %entry |
| ; NO-SZ-NEXT: vfmaddcph %zmm2, %zmm1, %zmm0 |
| ; NO-SZ-NEXT: retq |
| ; |
| ; HAS-SZ-LABEL: test2: |
| ; HAS-SZ: # %bb.0: # %entry |
| ; HAS-SZ-NEXT: vxorps %xmm3, %xmm3, %xmm3 |
| ; HAS-SZ-NEXT: vfmaddcph %zmm2, %zmm1, %zmm3 |
| ; HAS-SZ-NEXT: vaddph %zmm0, %zmm3, %zmm0 |
| ; HAS-SZ-NEXT: retq |
| entry: |
| %0 = bitcast <32 x half> %a to <16 x float> |
| %1 = bitcast <32 x half> %b to <16 x float> |
| %2 = tail call <16 x float> @llvm.x86.avx512fp16.mask.vfmadd.cph.512(<16 x float> %0, <16 x float> %1, <16 x float> zeroinitializer, i16 -1, i32 4) |
| %3 = bitcast <16 x float> %2 to <32 x half> |
| %add.i = fadd <32 x half> %3, %acc |
| ret <32 x half> %add.i |
| } |
| |
| define dso_local <16 x half> @test3(<16 x half> %acc, <16 x half> %a, <16 x half> %b) { |
| ; NO-SZ-LABEL: test3: |
| ; NO-SZ: # %bb.0: # %entry |
| ; NO-SZ-NEXT: vfcmaddcph %ymm2, %ymm1, %ymm0 |
| ; NO-SZ-NEXT: retq |
| ; |
| ; HAS-SZ-LABEL: test3: |
| ; HAS-SZ: # %bb.0: # %entry |
| ; HAS-SZ-NEXT: vxorps %xmm3, %xmm3, %xmm3 |
| ; HAS-SZ-NEXT: vfcmaddcph %ymm2, %ymm1, %ymm3 |
| ; HAS-SZ-NEXT: vaddph %ymm0, %ymm3, %ymm0 |
| ; HAS-SZ-NEXT: retq |
| entry: |
| %0 = bitcast <16 x half> %a to <8 x float> |
| %1 = bitcast <16 x half> %b to <8 x float> |
| %2 = tail call <8 x float> @llvm.x86.avx512fp16.mask.vfcmadd.cph.256(<8 x float> %0, <8 x float> %1, <8 x float> zeroinitializer, i8 -1) |
| %3 = bitcast <8 x float> %2 to <16 x half> |
| %add.i = fadd <16 x half> %3, %acc |
| ret <16 x half> %add.i |
| } |
| |
| define dso_local <16 x half> @test4(<16 x half> %acc, <16 x half> %a, <16 x half> %b) { |
| ; NO-SZ-LABEL: test4: |
| ; NO-SZ: # %bb.0: # %entry |
| ; NO-SZ-NEXT: vfmaddcph %ymm2, %ymm1, %ymm0 |
| ; NO-SZ-NEXT: retq |
| ; |
| ; HAS-SZ-LABEL: test4: |
| ; HAS-SZ: # %bb.0: # %entry |
| ; HAS-SZ-NEXT: vxorps %xmm3, %xmm3, %xmm3 |
| ; HAS-SZ-NEXT: vfmaddcph %ymm2, %ymm1, %ymm3 |
| ; HAS-SZ-NEXT: vaddph %ymm0, %ymm3, %ymm0 |
| ; HAS-SZ-NEXT: retq |
| entry: |
| %0 = bitcast <16 x half> %a to <8 x float> |
| %1 = bitcast <16 x half> %b to <8 x float> |
| %2 = tail call <8 x float> @llvm.x86.avx512fp16.mask.vfmadd.cph.256(<8 x float> %0, <8 x float> %1, <8 x float> zeroinitializer, i8 -1) |
| %3 = bitcast <8 x float> %2 to <16 x half> |
| %add.i = fadd <16 x half> %3, %acc |
| ret <16 x half> %add.i |
| } |
| |
| define dso_local <8 x half> @test5(<8 x half> %acc, <8 x half> %a, <8 x half> %b) { |
| ; NO-SZ-LABEL: test5: |
| ; NO-SZ: # %bb.0: # %entry |
| ; NO-SZ-NEXT: vfcmaddcph %xmm2, %xmm1, %xmm0 |
| ; NO-SZ-NEXT: retq |
| ; |
| ; HAS-SZ-LABEL: test5: |
| ; HAS-SZ: # %bb.0: # %entry |
| ; HAS-SZ-NEXT: vxorps %xmm3, %xmm3, %xmm3 |
| ; HAS-SZ-NEXT: vfcmaddcph %xmm2, %xmm1, %xmm3 |
| ; HAS-SZ-NEXT: vaddph %xmm0, %xmm3, %xmm0 |
| ; HAS-SZ-NEXT: retq |
| entry: |
| %0 = bitcast <8 x half> %a to <4 x float> |
| %1 = bitcast <8 x half> %b to <4 x float> |
| %2 = tail call <4 x float> @llvm.x86.avx512fp16.mask.vfcmadd.cph.128(<4 x float> %0, <4 x float> %1, <4 x float> zeroinitializer, i8 -1) |
| %3 = bitcast <4 x float> %2 to <8 x half> |
| %add.i = fadd <8 x half> %3, %acc |
| ret <8 x half> %add.i |
| } |
| |
| define dso_local <8 x half> @test6(<8 x half> %acc, <8 x half> %a, <8 x half> %b) { |
| ; NO-SZ-LABEL: test6: |
| ; NO-SZ: # %bb.0: # %entry |
| ; NO-SZ-NEXT: vfmaddcph %xmm2, %xmm1, %xmm0 |
| ; NO-SZ-NEXT: retq |
| ; |
| ; HAS-SZ-LABEL: test6: |
| ; HAS-SZ: # %bb.0: # %entry |
| ; HAS-SZ-NEXT: vxorps %xmm3, %xmm3, %xmm3 |
| ; HAS-SZ-NEXT: vfmaddcph %xmm2, %xmm1, %xmm3 |
| ; HAS-SZ-NEXT: vaddph %xmm0, %xmm3, %xmm0 |
| ; HAS-SZ-NEXT: retq |
| entry: |
| %0 = bitcast <8 x half> %a to <4 x float> |
| %1 = bitcast <8 x half> %b to <4 x float> |
| %2 = tail call <4 x float> @llvm.x86.avx512fp16.mask.vfmadd.cph.128(<4 x float> %0, <4 x float> %1, <4 x float> zeroinitializer, i8 -1) |
| %3 = bitcast <4 x float> %2 to <8 x half> |
| %add.i = fadd <8 x half> %3, %acc |
| ret <8 x half> %add.i |
| } |
| |
| ; FADD(acc, FMA(a, b, -0.0)) can be combined to FMA(a, b, acc) no matter if the nsz flag set. |
| define dso_local <32 x half> @test13(<32 x half> %acc, <32 x half> %a, <32 x half> %b) { |
| ; CHECK-LABEL: test13: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: vfcmaddcph %zmm2, %zmm1, %zmm0 |
| ; CHECK-NEXT: retq |
| entry: |
| %0 = bitcast <32 x half> %a to <16 x float> |
| %1 = bitcast <32 x half> %b to <16 x float> |
| %2 = tail call <16 x float> @llvm.x86.avx512fp16.mask.vfcmadd.cph.512(<16 x float> %0, <16 x float> %1, <16 x float> <float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000>, i16 -1, i32 4) |
| %3 = bitcast <16 x float> %2 to <32 x half> |
| %add.i = fadd <32 x half> %3, %acc |
| ret <32 x half> %add.i |
| } |
| |
| define dso_local <32 x half> @test14(<32 x half> %acc, <32 x half> %a, <32 x half> %b) { |
| ; CHECK-LABEL: test14: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: vfmaddcph %zmm2, %zmm1, %zmm0 |
| ; CHECK-NEXT: retq |
| entry: |
| %0 = bitcast <32 x half> %a to <16 x float> |
| %1 = bitcast <32 x half> %b to <16 x float> |
| %2 = tail call <16 x float> @llvm.x86.avx512fp16.mask.vfmadd.cph.512(<16 x float> %0, <16 x float> %1, <16 x float> <float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000>, i16 -1, i32 4) |
| %3 = bitcast <16 x float> %2 to <32 x half> |
| %add.i = fadd <32 x half> %3, %acc |
| ret <32 x half> %add.i |
| } |
| |
| define dso_local <16 x half> @test15(<16 x half> %acc, <16 x half> %a, <16 x half> %b) { |
| ; CHECK-LABEL: test15: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: vfcmaddcph %ymm2, %ymm1, %ymm0 |
| ; CHECK-NEXT: retq |
| entry: |
| %0 = bitcast <16 x half> %a to <8 x float> |
| %1 = bitcast <16 x half> %b to <8 x float> |
| %2 = tail call <8 x float> @llvm.x86.avx512fp16.mask.vfcmadd.cph.256(<8 x float> %0, <8 x float> %1, <8 x float> <float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000>, i8 -1) |
| %3 = bitcast <8 x float> %2 to <16 x half> |
| %add.i = fadd <16 x half> %3, %acc |
| ret <16 x half> %add.i |
| } |
| |
| define dso_local <16 x half> @test16(<16 x half> %acc, <16 x half> %a, <16 x half> %b) { |
| ; CHECK-LABEL: test16: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: vfmaddcph %ymm2, %ymm1, %ymm0 |
| ; CHECK-NEXT: retq |
| entry: |
| %0 = bitcast <16 x half> %a to <8 x float> |
| %1 = bitcast <16 x half> %b to <8 x float> |
| %2 = tail call <8 x float> @llvm.x86.avx512fp16.mask.vfmadd.cph.256(<8 x float> %0, <8 x float> %1, <8 x float> <float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000>, i8 -1) |
| %3 = bitcast <8 x float> %2 to <16 x half> |
| %add.i = fadd <16 x half> %3, %acc |
| ret <16 x half> %add.i |
| } |
| |
| define dso_local <8 x half> @test17(<8 x half> %acc, <8 x half> %a, <8 x half> %b) { |
| ; CHECK-LABEL: test17: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: vfcmaddcph %xmm2, %xmm1, %xmm0 |
| ; CHECK-NEXT: retq |
| entry: |
| %0 = bitcast <8 x half> %a to <4 x float> |
| %1 = bitcast <8 x half> %b to <4 x float> |
| %2 = tail call <4 x float> @llvm.x86.avx512fp16.mask.vfcmadd.cph.128(<4 x float> %0, <4 x float> %1, <4 x float> <float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000>, i8 -1) |
| %3 = bitcast <4 x float> %2 to <8 x half> |
| %add.i = fadd <8 x half> %3, %acc |
| ret <8 x half> %add.i |
| } |
| |
| define dso_local <8 x half> @test18(<8 x half> %acc, <8 x half> %a, <8 x half> %b) { |
| ; CHECK-LABEL: test18: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: vfmaddcph %xmm2, %xmm1, %xmm0 |
| ; CHECK-NEXT: retq |
| entry: |
| %0 = bitcast <8 x half> %a to <4 x float> |
| %1 = bitcast <8 x half> %b to <4 x float> |
| %2 = tail call <4 x float> @llvm.x86.avx512fp16.mask.vfmadd.cph.128(<4 x float> %0, <4 x float> %1, <4 x float> <float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000, float 0xB790000000000000>, i8 -1) |
| %3 = bitcast <4 x float> %2 to <8 x half> |
| %add.i = fadd <8 x half> %3, %acc |
| ret <8 x half> %add.i |
| } |
| |
| declare <16 x float> @llvm.x86.avx512fp16.mask.vfcmadd.cph.512(<16 x float>, <16 x float>, <16 x float>, i16, i32 immarg) |
| declare <16 x float> @llvm.x86.avx512fp16.mask.vfmadd.cph.512(<16 x float>, <16 x float>, <16 x float>, i16, i32 immarg) |
| declare <8 x float> @llvm.x86.avx512fp16.mask.vfcmadd.cph.256(<8 x float>, <8 x float>, <8 x float>, i8) |
| declare <8 x float> @llvm.x86.avx512fp16.mask.vfmadd.cph.256(<8 x float>, <8 x float>, <8 x float>, i8) |
| declare <4 x float> @llvm.x86.avx512fp16.mask.vfcmadd.cph.128(<4 x float>, <4 x float>, <4 x float>, i8) |
| declare <4 x float> @llvm.x86.avx512fp16.mask.vfmadd.cph.128(<4 x float>, <4 x float>, <4 x float>, i8) |