Files
clang-p2996/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-sincos.defined.ll
Matt Arsenault 54bda79335 AMDGPU: Simplify and improve sincos matching
The first trivial example I tried failed to merge due to the user scan
logic. Remove the complicated scan of users handling with distance
thresholds, with a same block restriction. The actual expansion of
sincos is basically the same size as sin or cos individually. Copy the
technique the generic optimization uses, which is to just use the
input instruction as the insert point or just insert at the start of
the entry block.

https://reviews.llvm.org/D156706
2023-08-02 17:48:35 -04:00

190 lines
9.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
; RUN: opt -S -mtriple=amdgcn-- -passes=amdgpu-simplifylib < %s | FileCheck %s
target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8"
; sin, cos, and sincos are already defined in the module.
define float @_Z3sinf(float %x) {
; CHECK-LABEL: define float @_Z3sinf
; CHECK-SAME: (float [[X:%.*]]) {
; CHECK-NEXT: [[RESULT:%.*]] = call float asm "
; CHECK-NEXT: ret float [[RESULT]]
;
%result = call float asm "; $0 = sin($1)","=v,v"(float %x)
ret float %result
}
define float @_Z3cosf(float %x) {
; CHECK-LABEL: define float @_Z3cosf
; CHECK-SAME: (float [[X:%.*]]) {
; CHECK-NEXT: [[RESULT:%.*]] = call float asm "
; CHECK-NEXT: ret float [[RESULT]]
;
%result = call float asm "; $0 = cos($1)","=v,v"(float %x)
ret float %result
}
define <2 x float> @_Z3sinDv2_f(<2 x float> %x) {
; CHECK-LABEL: define <2 x float> @_Z3sinDv2_f
; CHECK-SAME: (<2 x float> [[X:%.*]]) {
; CHECK-NEXT: [[RESULT:%.*]] = call <2 x float> asm "
; CHECK-NEXT: ret <2 x float> [[RESULT]]
;
%result = call <2 x float> asm "; $0 = sin($1)","=v,v"(<2 x float> %x)
ret <2 x float> %result
}
define <2 x float> @_Z3cosDv2_f(<2 x float> %x) {
; CHECK-LABEL: define <2 x float> @_Z3cosDv2_f
; CHECK-SAME: (<2 x float> [[X:%.*]]) {
; CHECK-NEXT: [[RESULT:%.*]] = call <2 x float> asm "
; CHECK-NEXT: ret <2 x float> [[RESULT]]
;
%result = call <2 x float> asm "; $0 = cos($1)","=v,v"(<2 x float> %x)
ret <2 x float> %result
}
define float @_Z6sincosfPU3AS5f(float %x, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define float @_Z6sincosfPU3AS5f
; CHECK-SAME: (float [[X:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: [[RESULT0:%.*]] = call float asm "
; CHECK-NEXT: [[RESULT1:%.*]] = call float asm "
; CHECK-NEXT: store float [[RESULT1]], ptr addrspace(5) [[PTR]], align 4
; CHECK-NEXT: ret float [[RESULT0]]
;
%result0 = call float asm "; $0 = sin($1)","=v,v"(float %x)
%result1 = call float asm "; $0 = cos($1)","=v,v"(float %x)
store float %result1, ptr addrspace(5) %ptr
ret float %result0
}
define <2 x float> @_Z6sincosDv2_fPU3AS5S_(<2 x float> %x, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define <2 x float> @_Z6sincosDv2_fPU3AS5S_
; CHECK-SAME: (<2 x float> [[X:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: [[RESULT0:%.*]] = call <2 x float> asm "
; CHECK-NEXT: [[RESULT1:%.*]] = call <2 x float> asm "
; CHECK-NEXT: store <2 x float> [[RESULT1]], ptr addrspace(5) [[PTR]], align 8
; CHECK-NEXT: ret <2 x float> [[RESULT0]]
;
%result0 = call <2 x float> asm "; $0 = sin($1)","=v,v"(<2 x float> %x)
%result1 = call <2 x float> asm "; $0 = cos($1)","=v,v"(<2 x float> %x)
store <2 x float> %result1, ptr addrspace(5) %ptr
ret <2 x float> %result0
}
define float @_Z6sincosfPU3AS0f(float %x, ptr %ptr) {
; CHECK-LABEL: define float @_Z6sincosfPU3AS0f
; CHECK-SAME: (float [[X:%.*]], ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[RESULT0:%.*]] = call float asm "
; CHECK-NEXT: [[RESULT1:%.*]] = call float asm "
; CHECK-NEXT: store float [[RESULT1]], ptr [[PTR]], align 4
; CHECK-NEXT: ret float [[RESULT0]]
;
%result0 = call float asm "; $0 = sin($1)","=v,v"(float %x)
%result1 = call float asm "; $0 = cos($1)","=v,v"(float %x)
store float %result1, ptr %ptr
ret float %result0
}
define <2 x float> @_Z6sincosDv2_fPU3AS0S_(<2 x float> %x, ptr %ptr) {
; CHECK-LABEL: define <2 x float> @_Z6sincosDv2_fPU3AS0S_
; CHECK-SAME: (<2 x float> [[X:%.*]], ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[RESULT0:%.*]] = call <2 x float> asm "
; CHECK-NEXT: [[RESULT1:%.*]] = call <2 x float> asm "
; CHECK-NEXT: store <2 x float> [[RESULT1]], ptr [[PTR]], align 8
; CHECK-NEXT: ret <2 x float> [[RESULT0]]
;
%result0 = call <2 x float> asm "; $0 = sin($1)","=v,v"(<2 x float> %x)
%result1 = call <2 x float> asm "; $0 = cos($1)","=v,v"(<2 x float> %x)
store <2 x float> %result1, ptr %ptr
ret <2 x float> %result0
}
define void @sincos_f32(float %x, ptr addrspace(1) nocapture writeonly %sin_out, ptr addrspace(1) nocapture writeonly %cos_out) {
; CHECK-LABEL: define void @sincos_f32
; CHECK-SAME: (float [[X:%.*]], ptr addrspace(1) nocapture writeonly [[SIN_OUT:%.*]], ptr addrspace(1) nocapture writeonly [[COS_OUT:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[__SINCOS_:%.*]] = alloca float, align 4, addrspace(5)
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(5) [[__SINCOS_]] to ptr
; CHECK-NEXT: [[TMP1:%.*]] = call contract float @_Z6sincosfPU3AS0f(float [[X]], ptr [[TMP0]])
; CHECK-NEXT: [[TMP2:%.*]] = load float, ptr addrspace(5) [[__SINCOS_]], align 4
; CHECK-NEXT: store float [[TMP1]], ptr addrspace(1) [[SIN_OUT]], align 4
; CHECK-NEXT: store float [[TMP2]], ptr addrspace(1) [[COS_OUT]], align 4
; CHECK-NEXT: ret void
;
entry:
%call = tail call contract float @_Z3sinf(float %x)
store float %call, ptr addrspace(1) %sin_out, align 4
%call1 = tail call contract float @_Z3cosf(float %x)
store float %call1, ptr addrspace(1) %cos_out, align 4
ret void
}
define void @sincos_f32_value_is_same_constantfp(ptr addrspace(1) nocapture writeonly %sin_out, ptr addrspace(1) nocapture writeonly %cos_out) {
; CHECK-LABEL: define void @sincos_f32_value_is_same_constantfp
; CHECK-SAME: (ptr addrspace(1) nocapture writeonly [[SIN_OUT:%.*]], ptr addrspace(1) nocapture writeonly [[COS_OUT:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[__SINCOS_:%.*]] = alloca float, align 4, addrspace(5)
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(5) [[__SINCOS_]] to ptr
; CHECK-NEXT: [[TMP1:%.*]] = call contract float @_Z6sincosfPU3AS0f(float 4.200000e+01, ptr [[TMP0]])
; CHECK-NEXT: [[TMP2:%.*]] = load float, ptr addrspace(5) [[__SINCOS_]], align 4
; CHECK-NEXT: store float [[TMP1]], ptr addrspace(1) [[SIN_OUT]], align 4
; CHECK-NEXT: store float [[TMP2]], ptr addrspace(1) [[COS_OUT]], align 4
; CHECK-NEXT: ret void
;
entry:
%call = tail call contract float @_Z3sinf(float 42.0)
store float %call, ptr addrspace(1) %sin_out, align 4
%call1 = tail call contract float @_Z3cosf(float 42.0)
store float %call1, ptr addrspace(1) %cos_out, align 4
ret void
}
define void @sincos_v2f32(<2 x float> %x, ptr addrspace(1) nocapture writeonly %sin_out, ptr addrspace(1) nocapture writeonly %cos_out) {
; GCN-LABEL: define void @sincos_v2f32
; GCN-SAME: (<2 x float> [[X:%.*]], ptr addrspace(1) nocapture writeonly [[SIN_OUT:%.*]], ptr addrspace(1) nocapture writeonly [[COS_OUT:%.*]]) local_unnamed_addr {
; GCN-NEXT: entry:
; GCN-NEXT: [[CALL:%.*]] = tail call contract <2 x float> @_Z3sinDv2_f(<2 x float> [[X]])
; GCN-NEXT: store <2 x float> [[CALL]], ptr addrspace(1) [[SIN_OUT]], align 8
; GCN-NEXT: [[CALL1:%.*]] = tail call contract <2 x float> @_Z3cosDv2_f(<2 x float> [[X]])
; GCN-NEXT: store <2 x float> [[CALL1]], ptr addrspace(1) [[COS_OUT]], align 8
; GCN-NEXT: ret void
;
; CHECK-LABEL: define void @sincos_v2f32
; CHECK-SAME: (<2 x float> [[X:%.*]], ptr addrspace(1) nocapture writeonly [[SIN_OUT:%.*]], ptr addrspace(1) nocapture writeonly [[COS_OUT:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[__SINCOS_:%.*]] = alloca <2 x float>, align 8, addrspace(5)
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(5) [[__SINCOS_]] to ptr
; CHECK-NEXT: [[TMP1:%.*]] = call contract <2 x float> @_Z6sincosDv2_fPU3AS0S_(<2 x float> [[X]], ptr [[TMP0]])
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x float>, ptr addrspace(5) [[__SINCOS_]], align 8
; CHECK-NEXT: store <2 x float> [[TMP1]], ptr addrspace(1) [[SIN_OUT]], align 8
; CHECK-NEXT: store <2 x float> [[TMP2]], ptr addrspace(1) [[COS_OUT]], align 8
; CHECK-NEXT: ret void
;
entry:
%call = tail call contract <2 x float> @_Z3sinDv2_f(<2 x float> %x)
store <2 x float> %call, ptr addrspace(1) %sin_out, align 8
%call1 = tail call contract <2 x float> @_Z3cosDv2_f(<2 x float> %x)
store <2 x float> %call1, ptr addrspace(1) %cos_out, align 8
ret void
}
define void @sincos_f32_nobuiltin_callsite(float %x, ptr addrspace(1) nocapture writeonly %sin_out, ptr addrspace(1) nocapture writeonly %cos_out) {
; CHECK-LABEL: define void @sincos_f32_nobuiltin_callsite
; CHECK-SAME: (float [[X:%.*]], ptr addrspace(1) nocapture writeonly [[SIN_OUT:%.*]], ptr addrspace(1) nocapture writeonly [[COS_OUT:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = tail call contract float @_Z3sinf(float [[X]]) #[[ATTR0:[0-9]+]]
; CHECK-NEXT: store float [[CALL]], ptr addrspace(1) [[SIN_OUT]], align 4
; CHECK-NEXT: [[CALL1:%.*]] = tail call contract float @_Z3cosf(float [[X]]) #[[ATTR0]]
; CHECK-NEXT: store float [[CALL1]], ptr addrspace(1) [[COS_OUT]], align 4
; CHECK-NEXT: ret void
;
entry:
%call = tail call contract float @_Z3sinf(float %x) nobuiltin
store float %call, ptr addrspace(1) %sin_out, align 4
%call1 = tail call contract float @_Z3cosf(float %x) nobuiltin
store float %call1, ptr addrspace(1) %cos_out, align 4
ret void
}