| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: opt -passes=slp-vectorizer -S -mtriple=amdgpu9.0a-amd-amdhsa < %s | FileCheck %s --check-prefixes=GFX90A | |
| ; RUN: opt -passes=slp-vectorizer -S -mtriple=amdgpu10.30-amd-amdhsa < %s | FileCheck %s --check-prefixes=GFX1030 | |
| ; Four approximate divisions of sums, added up by a reassociable reduction. | |
| ; The vector fdiv is the root of the tree and keeps the approximation flag of | |
| ; its scalar divisions, which the target lowers to a reciprocal and a multiply | |
| ; per lane, so the divisions and the sums feeding them vectorize. | |
| define float @div4_afn_sum(ptr addrspace(1) noalias readonly align 4 %a, ptr addrspace(1) noalias readonly align 4 %b, float %k, float %acc) { | |
| ; GFX90A-LABEL: define float @div4_afn_sum( | |
| ; GFX90A-SAME: ptr addrspace(1) noalias readonly align 4 [[A:%.*]], ptr addrspace(1) noalias readonly align 4 [[B:%.*]], float [[K:%.*]], float [[ACC:%.*]]) { | |
| ; GFX90A-NEXT: [[ENTRY:.*:]] | |
| ; GFX90A-NEXT: [[PA0:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[A]], i64 0 | |
| ; GFX90A-NEXT: [[PB0:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[B]], i64 0 | |
| ; GFX90A-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr addrspace(1) [[PA0]], align 4 | |
| ; GFX90A-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr addrspace(1) [[PB0]], align 4 | |
| ; GFX90A-NEXT: [[TMP2:%.*]] = insertelement <4 x float> poison, float [[K]], i64 0 | |
| ; GFX90A-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> poison, <4 x i32> zeroinitializer | |
| ; GFX90A-NEXT: [[TMP4:%.*]] = fadd <4 x float> [[TMP0]], [[TMP3]] | |
| ; GFX90A-NEXT: [[TMP5:%.*]] = fdiv afn <4 x float> [[TMP4]], [[TMP1]] | |
| ; GFX90A-NEXT: [[TMP6:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[TMP5]]) | |
| ; GFX90A-NEXT: [[OP_RDX:%.*]] = fadd fast float [[TMP6]], [[ACC]] | |
| ; GFX90A-NEXT: ret float [[OP_RDX]] | |
| ; | |
| ; GFX1030-LABEL: define float @div4_afn_sum( | |
| ; GFX1030-SAME: ptr addrspace(1) noalias readonly align 4 [[A:%.*]], ptr addrspace(1) noalias readonly align 4 [[B:%.*]], float [[K:%.*]], float [[ACC:%.*]]) { | |
| ; GFX1030-NEXT: [[ENTRY:.*:]] | |
| ; GFX1030-NEXT: [[PA0:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[A]], i64 0 | |
| ; GFX1030-NEXT: [[PB0:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[B]], i64 0 | |
| ; GFX1030-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr addrspace(1) [[PA0]], align 4 | |
| ; GFX1030-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr addrspace(1) [[PB0]], align 4 | |
| ; GFX1030-NEXT: [[TMP2:%.*]] = insertelement <4 x float> poison, float [[K]], i64 0 | |
| ; GFX1030-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> poison, <4 x i32> zeroinitializer | |
| ; GFX1030-NEXT: [[TMP4:%.*]] = fadd <4 x float> [[TMP0]], [[TMP3]] | |
| ; GFX1030-NEXT: [[TMP5:%.*]] = fdiv afn <4 x float> [[TMP4]], [[TMP1]] | |
| ; GFX1030-NEXT: [[TMP6:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[TMP5]]) | |
| ; GFX1030-NEXT: [[OP_RDX:%.*]] = fadd fast float [[TMP6]], [[ACC]] | |
| ; GFX1030-NEXT: ret float [[OP_RDX]] | |
| ; | |
| entry: | |
| %pa0 = getelementptr inbounds float, ptr addrspace(1) %a, i64 0 | |
| %la0 = load float, ptr addrspace(1) %pa0, align 4 | |
| %pb0 = getelementptr inbounds float, ptr addrspace(1) %b, i64 0 | |
| %lb0 = load float, ptr addrspace(1) %pb0, align 4 | |
| %t0 = fadd float %la0, %k | |
| %d0 = fdiv afn float %t0, %lb0 | |
| %pa1 = getelementptr inbounds float, ptr addrspace(1) %a, i64 1 | |
| %la1 = load float, ptr addrspace(1) %pa1, align 4 | |
| %pb1 = getelementptr inbounds float, ptr addrspace(1) %b, i64 1 | |
| %lb1 = load float, ptr addrspace(1) %pb1, align 4 | |
| %t1 = fadd float %la1, %k | |
| %d1 = fdiv afn float %t1, %lb1 | |
| %pa2 = getelementptr inbounds float, ptr addrspace(1) %a, i64 2 | |
| %la2 = load float, ptr addrspace(1) %pa2, align 4 | |
| %pb2 = getelementptr inbounds float, ptr addrspace(1) %b, i64 2 | |
| %lb2 = load float, ptr addrspace(1) %pb2, align 4 | |
| %t2 = fadd float %la2, %k | |
| %d2 = fdiv afn float %t2, %lb2 | |
| %pa3 = getelementptr inbounds float, ptr addrspace(1) %a, i64 3 | |
| %la3 = load float, ptr addrspace(1) %pa3, align 4 | |
| %pb3 = getelementptr inbounds float, ptr addrspace(1) %b, i64 3 | |
| %lb3 = load float, ptr addrspace(1) %pb3, align 4 | |
| %t3 = fadd float %la3, %k | |
| %d3 = fdiv afn float %t3, %lb3 | |
| %s0 = fadd fast float %acc, %d0 | |
| %s1 = fadd fast float %s0, %d1 | |
| %s2 = fadd fast float %s1, %d2 | |
| %s3 = fadd fast float %s2, %d3 | |
| ret float %s3 | |
| } |