blob: 4cf969473147fd79ead11dfe02f163be05029928 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -mtriple=amdgpu9.00-amd-amdhsa -passes=slp-vectorizer < %s | FileCheck -check-prefixes=GFX900 %s
; RUN: opt -S -mtriple=amdgpu9.50-amd-amdhsa -passes=slp-vectorizer < %s | FileCheck -check-prefixes=GFX950 %s
; RUN: opt -S -mtriple=amdgpu12.50-amd-amdhsa -passes=slp-vectorizer < %s | FileCheck -check-prefixes=GFX1250 %s
; Reduced from an MXFP softmax kernel on gfx1250. Packed-f32 pair formation
; is priced too high for these shapes, so both stay scalar. gfx900 has no
; packed f32 ops; gfx950 does. The three targets produce the same IR, and
; each has its own checks.
; The softmax scale is multiplied into two lanes of a loaded pair, and each
; product is then broadcast over a <4 x float> operand. The two fmuls stay
; scalar, and each product is splatted with its own insertelement.
define amdgpu_kernel void @softmax_scale_splat(ptr addrspace(3) %in, ptr addrspace(3) %out, float %scale, <4 x float> %x0, <4 x float> %x1) {
; GFX900-LABEL: define amdgpu_kernel void @softmax_scale_splat(
; GFX900-SAME: ptr addrspace(3) [[IN:%.*]], ptr addrspace(3) [[OUT:%.*]], float [[SCALE:%.*]], <4 x float> [[X0:%.*]], <4 x float> [[X1:%.*]]) {
; GFX900-NEXT: [[M:%.*]] = load <2 x float>, ptr addrspace(3) [[IN]], align 16
; GFX900-NEXT: [[M0:%.*]] = extractelement <2 x float> [[M]], i64 0
; GFX900-NEXT: [[M1:%.*]] = extractelement <2 x float> [[M]], i64 1
; GFX900-NEXT: [[B0:%.*]] = fmul float [[SCALE]], [[M0]]
; GFX900-NEXT: [[B1:%.*]] = fmul float [[SCALE]], [[M1]]
; GFX900-NEXT: [[I0:%.*]] = insertelement <4 x float> poison, float [[B0]], i64 0
; GFX900-NEXT: [[S0:%.*]] = shufflevector <4 x float> [[I0]], <4 x float> poison, <4 x i32> zeroinitializer
; GFX900-NEXT: [[I1:%.*]] = insertelement <4 x float> poison, float [[B1]], i64 0
; GFX900-NEXT: [[S1:%.*]] = shufflevector <4 x float> [[I1]], <4 x float> poison, <4 x i32> zeroinitializer
; GFX900-NEXT: [[R0:%.*]] = fsub <4 x float> [[X0]], [[S0]]
; GFX900-NEXT: [[R1:%.*]] = fsub <4 x float> [[X1]], [[S1]]
; GFX900-NEXT: store <4 x float> [[R0]], ptr addrspace(3) [[OUT]], align 16
; GFX900-NEXT: [[O1:%.*]] = getelementptr inbounds <4 x float>, ptr addrspace(3) [[OUT]], i32 1
; GFX900-NEXT: store <4 x float> [[R1]], ptr addrspace(3) [[O1]], align 16
; GFX900-NEXT: ret void
;
; GFX950-LABEL: define amdgpu_kernel void @softmax_scale_splat(
; GFX950-SAME: ptr addrspace(3) [[IN:%.*]], ptr addrspace(3) [[OUT:%.*]], float [[SCALE:%.*]], <4 x float> [[X0:%.*]], <4 x float> [[X1:%.*]]) {
; GFX950-NEXT: [[M:%.*]] = load <2 x float>, ptr addrspace(3) [[IN]], align 16
; GFX950-NEXT: [[M0:%.*]] = extractelement <2 x float> [[M]], i64 0
; GFX950-NEXT: [[M1:%.*]] = extractelement <2 x float> [[M]], i64 1
; GFX950-NEXT: [[B0:%.*]] = fmul float [[SCALE]], [[M0]]
; GFX950-NEXT: [[B1:%.*]] = fmul float [[SCALE]], [[M1]]
; GFX950-NEXT: [[I0:%.*]] = insertelement <4 x float> poison, float [[B0]], i64 0
; GFX950-NEXT: [[S0:%.*]] = shufflevector <4 x float> [[I0]], <4 x float> poison, <4 x i32> zeroinitializer
; GFX950-NEXT: [[I1:%.*]] = insertelement <4 x float> poison, float [[B1]], i64 0
; GFX950-NEXT: [[S1:%.*]] = shufflevector <4 x float> [[I1]], <4 x float> poison, <4 x i32> zeroinitializer
; GFX950-NEXT: [[R0:%.*]] = fsub <4 x float> [[X0]], [[S0]]
; GFX950-NEXT: [[R1:%.*]] = fsub <4 x float> [[X1]], [[S1]]
; GFX950-NEXT: store <4 x float> [[R0]], ptr addrspace(3) [[OUT]], align 16
; GFX950-NEXT: [[O1:%.*]] = getelementptr inbounds <4 x float>, ptr addrspace(3) [[OUT]], i32 1
; GFX950-NEXT: store <4 x float> [[R1]], ptr addrspace(3) [[O1]], align 16
; GFX950-NEXT: ret void
;
; GFX1250-LABEL: define amdgpu_kernel void @softmax_scale_splat(
; GFX1250-SAME: ptr addrspace(3) [[IN:%.*]], ptr addrspace(3) [[OUT:%.*]], float [[SCALE:%.*]], <4 x float> [[X0:%.*]], <4 x float> [[X1:%.*]]) {
; GFX1250-NEXT: [[M:%.*]] = load <2 x float>, ptr addrspace(3) [[IN]], align 16
; GFX1250-NEXT: [[M0:%.*]] = extractelement <2 x float> [[M]], i64 0
; GFX1250-NEXT: [[M1:%.*]] = extractelement <2 x float> [[M]], i64 1
; GFX1250-NEXT: [[B0:%.*]] = fmul float [[SCALE]], [[M0]]
; GFX1250-NEXT: [[B1:%.*]] = fmul float [[SCALE]], [[M1]]
; GFX1250-NEXT: [[I0:%.*]] = insertelement <4 x float> poison, float [[B0]], i64 0
; GFX1250-NEXT: [[S0:%.*]] = shufflevector <4 x float> [[I0]], <4 x float> poison, <4 x i32> zeroinitializer
; GFX1250-NEXT: [[I1:%.*]] = insertelement <4 x float> poison, float [[B1]], i64 0
; GFX1250-NEXT: [[S1:%.*]] = shufflevector <4 x float> [[I1]], <4 x float> poison, <4 x i32> zeroinitializer
; GFX1250-NEXT: [[R0:%.*]] = fsub <4 x float> [[X0]], [[S0]]
; GFX1250-NEXT: [[R1:%.*]] = fsub <4 x float> [[X1]], [[S1]]
; GFX1250-NEXT: store <4 x float> [[R0]], ptr addrspace(3) [[OUT]], align 16
; GFX1250-NEXT: [[O1:%.*]] = getelementptr inbounds <4 x float>, ptr addrspace(3) [[OUT]], i32 1
; GFX1250-NEXT: store <4 x float> [[R1]], ptr addrspace(3) [[O1]], align 16
; GFX1250-NEXT: ret void
;
%m = load <2 x float>, ptr addrspace(3) %in, align 16
%m0 = extractelement <2 x float> %m, i64 0
%m1 = extractelement <2 x float> %m, i64 1
%b0 = fmul float %scale, %m0
%b1 = fmul float %scale, %m1
%i0 = insertelement <4 x float> poison, float %b0, i64 0
%s0 = shufflevector <4 x float> %i0, <4 x float> poison, <4 x i32> zeroinitializer
%i1 = insertelement <4 x float> poison, float %b1, i64 0
%s1 = shufflevector <4 x float> %i1, <4 x float> poison, <4 x i32> zeroinitializer
%r0 = fsub <4 x float> %x0, %s0
%r1 = fsub <4 x float> %x1, %s1
store <4 x float> %r0, ptr addrspace(3) %out, align 16
%o1 = getelementptr inbounds <4 x float>, ptr addrspace(3) %out, i32 1
store <4 x float> %r1, ptr addrspace(3) %o1, align 16
ret void
}
; The row sums of two <4 x float> accumulators are reduced lane by lane and
; the two sums are stored as a pair. The reduction stays six scalar fadds, and
; the stored pair is built with insertelement.
define amdgpu_kernel void @softmax_row_sum(ptr addrspace(3) %out, <4 x float> %p, <4 x float> %q) {
; GFX900-LABEL: define amdgpu_kernel void @softmax_row_sum(
; GFX900-SAME: ptr addrspace(3) [[OUT:%.*]], <4 x float> [[P:%.*]], <4 x float> [[Q:%.*]]) {
; GFX900-NEXT: [[P0:%.*]] = extractelement <4 x float> [[P]], i64 0
; GFX900-NEXT: [[P1:%.*]] = extractelement <4 x float> [[P]], i64 1
; GFX900-NEXT: [[P2:%.*]] = extractelement <4 x float> [[P]], i64 2
; GFX900-NEXT: [[P3:%.*]] = extractelement <4 x float> [[P]], i64 3
; GFX900-NEXT: [[Q0:%.*]] = extractelement <4 x float> [[Q]], i64 0
; GFX900-NEXT: [[Q1:%.*]] = extractelement <4 x float> [[Q]], i64 1
; GFX900-NEXT: [[Q2:%.*]] = extractelement <4 x float> [[Q]], i64 2
; GFX900-NEXT: [[Q3:%.*]] = extractelement <4 x float> [[Q]], i64 3
; GFX900-NEXT: [[PA:%.*]] = fadd float [[P0]], [[P1]]
; GFX900-NEXT: [[PB:%.*]] = fadd float [[P2]], [[P3]]
; GFX900-NEXT: [[PS:%.*]] = fadd float [[PA]], [[PB]]
; GFX900-NEXT: [[QA:%.*]] = fadd float [[Q0]], [[Q1]]
; GFX900-NEXT: [[QB:%.*]] = fadd float [[Q2]], [[Q3]]
; GFX900-NEXT: [[QS:%.*]] = fadd float [[QA]], [[QB]]
; GFX900-NEXT: [[V0:%.*]] = insertelement <2 x float> poison, float [[PS]], i64 0
; GFX900-NEXT: [[V1:%.*]] = insertelement <2 x float> [[V0]], float [[QS]], i64 1
; GFX900-NEXT: store <2 x float> [[V1]], ptr addrspace(3) [[OUT]], align 8
; GFX900-NEXT: ret void
;
; GFX950-LABEL: define amdgpu_kernel void @softmax_row_sum(
; GFX950-SAME: ptr addrspace(3) [[OUT:%.*]], <4 x float> [[P:%.*]], <4 x float> [[Q:%.*]]) {
; GFX950-NEXT: [[P0:%.*]] = extractelement <4 x float> [[P]], i64 0
; GFX950-NEXT: [[P1:%.*]] = extractelement <4 x float> [[P]], i64 1
; GFX950-NEXT: [[P2:%.*]] = extractelement <4 x float> [[P]], i64 2
; GFX950-NEXT: [[P3:%.*]] = extractelement <4 x float> [[P]], i64 3
; GFX950-NEXT: [[Q0:%.*]] = extractelement <4 x float> [[Q]], i64 0
; GFX950-NEXT: [[Q1:%.*]] = extractelement <4 x float> [[Q]], i64 1
; GFX950-NEXT: [[Q2:%.*]] = extractelement <4 x float> [[Q]], i64 2
; GFX950-NEXT: [[Q3:%.*]] = extractelement <4 x float> [[Q]], i64 3
; GFX950-NEXT: [[PA:%.*]] = fadd float [[P0]], [[P1]]
; GFX950-NEXT: [[PB:%.*]] = fadd float [[P2]], [[P3]]
; GFX950-NEXT: [[PS:%.*]] = fadd float [[PA]], [[PB]]
; GFX950-NEXT: [[QA:%.*]] = fadd float [[Q0]], [[Q1]]
; GFX950-NEXT: [[QB:%.*]] = fadd float [[Q2]], [[Q3]]
; GFX950-NEXT: [[QS:%.*]] = fadd float [[QA]], [[QB]]
; GFX950-NEXT: [[V0:%.*]] = insertelement <2 x float> poison, float [[PS]], i64 0
; GFX950-NEXT: [[V1:%.*]] = insertelement <2 x float> [[V0]], float [[QS]], i64 1
; GFX950-NEXT: store <2 x float> [[V1]], ptr addrspace(3) [[OUT]], align 8
; GFX950-NEXT: ret void
;
; GFX1250-LABEL: define amdgpu_kernel void @softmax_row_sum(
; GFX1250-SAME: ptr addrspace(3) [[OUT:%.*]], <4 x float> [[P:%.*]], <4 x float> [[Q:%.*]]) {
; GFX1250-NEXT: [[P0:%.*]] = extractelement <4 x float> [[P]], i64 0
; GFX1250-NEXT: [[P1:%.*]] = extractelement <4 x float> [[P]], i64 1
; GFX1250-NEXT: [[P2:%.*]] = extractelement <4 x float> [[P]], i64 2
; GFX1250-NEXT: [[P3:%.*]] = extractelement <4 x float> [[P]], i64 3
; GFX1250-NEXT: [[Q0:%.*]] = extractelement <4 x float> [[Q]], i64 0
; GFX1250-NEXT: [[Q1:%.*]] = extractelement <4 x float> [[Q]], i64 1
; GFX1250-NEXT: [[Q2:%.*]] = extractelement <4 x float> [[Q]], i64 2
; GFX1250-NEXT: [[Q3:%.*]] = extractelement <4 x float> [[Q]], i64 3
; GFX1250-NEXT: [[PA:%.*]] = fadd float [[P0]], [[P1]]
; GFX1250-NEXT: [[PB:%.*]] = fadd float [[P2]], [[P3]]
; GFX1250-NEXT: [[PS:%.*]] = fadd float [[PA]], [[PB]]
; GFX1250-NEXT: [[QA:%.*]] = fadd float [[Q0]], [[Q1]]
; GFX1250-NEXT: [[QB:%.*]] = fadd float [[Q2]], [[Q3]]
; GFX1250-NEXT: [[QS:%.*]] = fadd float [[QA]], [[QB]]
; GFX1250-NEXT: [[V0:%.*]] = insertelement <2 x float> poison, float [[PS]], i64 0
; GFX1250-NEXT: [[V1:%.*]] = insertelement <2 x float> [[V0]], float [[QS]], i64 1
; GFX1250-NEXT: store <2 x float> [[V1]], ptr addrspace(3) [[OUT]], align 8
; GFX1250-NEXT: ret void
;
%p0 = extractelement <4 x float> %p, i64 0
%p1 = extractelement <4 x float> %p, i64 1
%p2 = extractelement <4 x float> %p, i64 2
%p3 = extractelement <4 x float> %p, i64 3
%q0 = extractelement <4 x float> %q, i64 0
%q1 = extractelement <4 x float> %q, i64 1
%q2 = extractelement <4 x float> %q, i64 2
%q3 = extractelement <4 x float> %q, i64 3
%pa = fadd float %p0, %p1
%pb = fadd float %p2, %p3
%ps = fadd float %pa, %pb
%qa = fadd float %q0, %q1
%qb = fadd float %q2, %q3
%qs = fadd float %qa, %qb
%v0 = insertelement <2 x float> poison, float %ps, i64 0
%v1 = insertelement <2 x float> %v0, float %qs, i64 1
store <2 x float> %v1, ptr addrspace(3) %out, align 8
ret void
}