CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
248 lines
9.9 KiB
LLVM
248 lines
9.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt < %s -passes=nvptx-ir-peephole -S | FileCheck %s
|
|
|
|
target triple = "nvptx64-nvidia-cuda"
|
|
|
|
; fsub(fmul(a, b), c) => fma(a, b, fneg(c))
|
|
define float @test_fsub_fmul_c(float %a, float %b, float %c) {
|
|
; CHECK-LABEL: define float @test_fsub_fmul_c(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], float [[C:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[C]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call contract float @llvm.fma.f32(float [[A]], float [[B]], float [[TMP1]])
|
|
; CHECK-NEXT: ret float [[TMP2]]
|
|
;
|
|
%mul = fmul contract float %a, %b
|
|
%sub = fsub contract float %mul, %c
|
|
ret float %sub
|
|
}
|
|
|
|
|
|
; fsub(c, fmul(a, b)) => fma(-a, b, c)
|
|
define float @test_fsub_c_fmul(float %a, float %b, float %c) {
|
|
; CHECK-LABEL: define float @test_fsub_c_fmul(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], float [[C:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[A]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call contract float @llvm.fma.f32(float [[TMP1]], float [[B]], float [[C]])
|
|
; CHECK-NEXT: ret float [[TMP2]]
|
|
;
|
|
%mul = fmul contract float %a, %b
|
|
%sub = fsub contract float %c, %mul
|
|
ret float %sub
|
|
}
|
|
|
|
|
|
; fsub(fmul(a, b), fmul(c, d)) => fma(a, b, fneg(fmul(c, d)))
|
|
define float @test_fsub_fmul_fmul(float %a, float %b, float %c, float %d) {
|
|
; CHECK-LABEL: define float @test_fsub_fmul_fmul(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], float [[C:%.*]], float [[D:%.*]]) {
|
|
; CHECK-NEXT: [[MUL2:%.*]] = fmul contract float [[C]], [[D]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[MUL2]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call contract float @llvm.fma.f32(float [[A]], float [[B]], float [[TMP1]])
|
|
; CHECK-NEXT: ret float [[TMP2]]
|
|
;
|
|
%mul1 = fmul contract float %a, %b
|
|
%mul2 = fmul contract float %c, %d
|
|
%sub = fsub contract float %mul1, %mul2
|
|
ret float %sub
|
|
}
|
|
|
|
|
|
; fsub(fmul(a, b), fmul(c, d)) => fma(fneg(c), d, fmul(a, b)))
|
|
; fmul(a, b) has multiple uses.
|
|
define float @test_fsub_fmul_fmul_multiple_use(float %a, float %b, float %c, float %d) {
|
|
; CHECK-LABEL: define float @test_fsub_fmul_fmul_multiple_use(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], float [[C:%.*]], float [[D:%.*]]) {
|
|
; CHECK-NEXT: [[MUL1:%.*]] = fmul contract float [[A]], [[B]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[C]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call contract float @llvm.fma.f32(float [[TMP1]], float [[D]], float [[MUL1]])
|
|
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP2]], [[MUL1]]
|
|
; CHECK-NEXT: ret float [[ADD]]
|
|
;
|
|
%mul1 = fmul contract float %a, %b
|
|
%mul2 = fmul contract float %c, %d
|
|
%sub = fsub contract float %mul1, %mul2
|
|
%add = fadd float %sub, %mul1
|
|
ret float %add
|
|
}
|
|
|
|
|
|
; fsub(fmul(a, b), c) => fma(a, b, fneg(c)) where fsub and fmul are in different BBs
|
|
define float @test_fsub_fmul_different_BB(float %a, float %b, float %c, i32 %n) {
|
|
; CHECK-LABEL: define float @test_fsub_fmul_different_BB(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], float [[C:%.*]], i32 [[N:%.*]]) {
|
|
; CHECK-NEXT: [[INIT:.*]]:
|
|
; CHECK-NEXT: [[CMP_ITER:%.*]] = icmp sgt i32 [[N]], 10
|
|
; CHECK-NEXT: br i1 [[CMP_ITER]], label %[[ITERATION:.*]], label %[[EXIT:.*]]
|
|
; CHECK: [[ITERATION]]:
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[INIT]] ], [ [[I_NEXT:%.*]], %[[ITERATION]] ]
|
|
; CHECK-NEXT: [[ACC:%.*]] = phi float [ [[C]], %[[INIT]] ], [ [[ACC_NEXT:%.*]], %[[ITERATION]] ]
|
|
; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
|
|
; CHECK-NEXT: [[ACC_NEXT]] = fadd contract float [[ACC]], 1.000000e+00
|
|
; CHECK-NEXT: [[CMP_LOOP:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
|
; CHECK-NEXT: br i1 [[CMP_LOOP]], label %[[ITERATION]], label %[[EXIT]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: [[C_PHI:%.*]] = phi float [ [[C]], %[[INIT]] ], [ [[ACC_NEXT]], %[[ITERATION]] ]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = fneg contract float [[C_PHI]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call contract float @llvm.fma.f32(float [[A]], float [[B]], float [[TMP0]])
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
init:
|
|
%mul = fmul contract float %a, %b
|
|
%cmp_iter = icmp sgt i32 %n, 10
|
|
br i1 %cmp_iter, label %iteration, label %exit
|
|
|
|
iteration:
|
|
%i = phi i32 [ 0, %init ], [ %i_next, %iteration ]
|
|
%acc = phi float [ %c, %init ], [ %acc_next, %iteration ]
|
|
%i_next = add i32 %i, 1
|
|
%acc_next = fadd contract float %acc, 1.0
|
|
%cmp_loop = icmp slt i32 %i_next, %n
|
|
br i1 %cmp_loop, label %iteration, label %exit
|
|
|
|
exit:
|
|
%c_phi = phi float [ %c, %init ], [ %acc_next, %iteration ]
|
|
%sub = fsub contract float %mul, %c_phi
|
|
ret float %sub
|
|
}
|
|
|
|
|
|
; fadd(fmul(a, b), c) => fma(a, b, c)
|
|
define float @test_fadd_fmul_c(float %a, float %b, float %c) {
|
|
; CHECK-LABEL: define float @test_fadd_fmul_c(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], float [[C:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call contract float @llvm.fma.f32(float [[A]], float [[B]], float [[C]])
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%mul = fmul contract float %a, %b
|
|
%add = fadd contract float %mul, %c
|
|
ret float %add
|
|
}
|
|
|
|
|
|
; fadd(c, fmul(a, b)) => fma(a, b, c)
|
|
define float @test_fadd_c_fmul(float %a, float %b, float %c) {
|
|
; CHECK-LABEL: define float @test_fadd_c_fmul(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], float [[C:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call contract float @llvm.fma.f32(float [[A]], float [[B]], float [[C]])
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%mul = fmul contract float %a, %b
|
|
%add = fadd contract float %c, %mul
|
|
ret float %add
|
|
}
|
|
|
|
|
|
; fadd(fmul(a, b), fmul(c, d)) => fma(a, b, fmul(c, d))
|
|
define float @test_fadd_fmul_fmul(float %a, float %b, float %c, float %d) {
|
|
; CHECK-LABEL: define float @test_fadd_fmul_fmul(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], float [[C:%.*]], float [[D:%.*]]) {
|
|
; CHECK-NEXT: [[MUL2:%.*]] = fmul contract float [[C]], [[D]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call contract float @llvm.fma.f32(float [[A]], float [[B]], float [[MUL2]])
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%mul1 = fmul contract float %a, %b
|
|
%mul2 = fmul contract float %c, %d
|
|
%add = fadd contract float %mul1, %mul2
|
|
ret float %add
|
|
}
|
|
|
|
|
|
; fadd(fmul(a, b), c) => fma(a, b, c) where fadd and fmul are in different BBs
|
|
define float @test_fadd_fmul_different_BB(float %a, float %b, float %c, i32 %n) {
|
|
; CHECK-LABEL: define float @test_fadd_fmul_different_BB(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], float [[C:%.*]], i32 [[N:%.*]]) {
|
|
; CHECK-NEXT: [[INIT:.*]]:
|
|
; CHECK-NEXT: [[CMP_ITER:%.*]] = icmp sgt i32 [[N]], 10
|
|
; CHECK-NEXT: br i1 [[CMP_ITER]], label %[[ITERATION:.*]], label %[[EXIT:.*]]
|
|
; CHECK: [[ITERATION]]:
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[INIT]] ], [ [[I_NEXT:%.*]], %[[ITERATION]] ]
|
|
; CHECK-NEXT: [[ACC:%.*]] = phi float [ [[C]], %[[INIT]] ], [ [[ACC_NEXT:%.*]], %[[ITERATION]] ]
|
|
; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
|
|
; CHECK-NEXT: [[ACC_NEXT]] = fadd contract float [[ACC]], 1.000000e+00
|
|
; CHECK-NEXT: [[CMP_LOOP:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
|
; CHECK-NEXT: br i1 [[CMP_LOOP]], label %[[ITERATION]], label %[[EXIT]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: [[C_PHI:%.*]] = phi float [ [[C]], %[[INIT]] ], [ [[ACC_NEXT]], %[[ITERATION]] ]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call contract float @llvm.fma.f32(float [[A]], float [[B]], float [[C_PHI]])
|
|
; CHECK-NEXT: ret float [[TMP0]]
|
|
;
|
|
init:
|
|
%mul = fmul contract float %a, %b
|
|
%cmp_iter = icmp sgt i32 %n, 10
|
|
br i1 %cmp_iter, label %iteration, label %exit
|
|
|
|
iteration:
|
|
%i = phi i32 [ 0, %init ], [ %i_next, %iteration ]
|
|
%acc = phi float [ %c, %init ], [ %acc_next, %iteration ]
|
|
%i_next = add i32 %i, 1
|
|
%acc_next = fadd contract float %acc, 1.0
|
|
%cmp_loop = icmp slt i32 %i_next, %n
|
|
br i1 %cmp_loop, label %iteration, label %exit
|
|
|
|
exit:
|
|
%c_phi = phi float [ %c, %init ], [ %acc_next, %iteration ]
|
|
%add = fadd contract float %mul, %c_phi
|
|
ret float %add
|
|
}
|
|
|
|
|
|
; These scenarios shouldn't work.
|
|
; fadd(fpext(fmul(a, b)), c) => fma(fpext(a), fpext(b), c)
|
|
define double @test_fadd_fpext_fmul_c(float %a, float %b, double %c) {
|
|
; CHECK-LABEL: define double @test_fadd_fpext_fmul_c(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], double [[C:%.*]]) {
|
|
; CHECK-NEXT: [[MUL:%.*]] = fmul contract float [[A]], [[B]]
|
|
; CHECK-NEXT: [[EXT:%.*]] = fpext float [[MUL]] to double
|
|
; CHECK-NEXT: [[ADD:%.*]] = fadd contract double [[EXT]], [[C]]
|
|
; CHECK-NEXT: ret double [[ADD]]
|
|
;
|
|
%mul = fmul contract float %a, %b
|
|
%ext = fpext float %mul to double
|
|
%add = fadd contract double %ext, %c
|
|
ret double %add
|
|
}
|
|
|
|
|
|
; fadd(c, fpext(fmul(a, b))) => fma(fpext(a), fpext(b), c)
|
|
define double @test_fadd_c_fpext_fmul(float %a, float %b, double %c) {
|
|
; CHECK-LABEL: define double @test_fadd_c_fpext_fmul(
|
|
; CHECK-SAME: float [[A:%.*]], float [[B:%.*]], double [[C:%.*]]) {
|
|
; CHECK-NEXT: [[MUL:%.*]] = fmul contract float [[A]], [[B]]
|
|
; CHECK-NEXT: [[EXT:%.*]] = fpext float [[MUL]] to double
|
|
; CHECK-NEXT: [[ADD:%.*]] = fadd contract double [[C]], [[EXT]]
|
|
; CHECK-NEXT: ret double [[ADD]]
|
|
;
|
|
%mul = fmul contract float %a, %b
|
|
%ext = fpext float %mul to double
|
|
%add = fadd contract double %c, %ext
|
|
ret double %add
|
|
}
|
|
|
|
|
|
; Double precision tests
|
|
; fsub(fmul(a, b), c) => fma(a, b, fneg(c))
|
|
define double @test_fsub_fmul_c_double(double %a, double %b, double %c) {
|
|
; CHECK-LABEL: define double @test_fsub_fmul_c_double(
|
|
; CHECK-SAME: double [[A:%.*]], double [[B:%.*]], double [[C:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fneg contract double [[C]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call contract double @llvm.fma.f64(double [[A]], double [[B]], double [[TMP1]])
|
|
; CHECK-NEXT: ret double [[TMP2]]
|
|
;
|
|
%mul = fmul contract double %a, %b
|
|
%sub = fsub contract double %mul, %c
|
|
ret double %sub
|
|
}
|
|
|
|
|
|
; fadd(fmul(a, b), c) => fma(a, b, c)
|
|
define double @test_fadd_fmul_c_double(double %a, double %b, double %c) {
|
|
; CHECK-LABEL: define double @test_fadd_fmul_c_double(
|
|
; CHECK-SAME: double [[A:%.*]], double [[B:%.*]], double [[C:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call contract double @llvm.fma.f64(double [[A]], double [[B]], double [[C]])
|
|
; CHECK-NEXT: ret double [[TMP1]]
|
|
;
|
|
%mul = fmul contract double %a, %b
|
|
%add = fadd contract double %mul, %c
|
|
ret double %add
|
|
}
|