-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NFC][AMDGPU] Pre-commit tests for IR variant - isFMAFasterThanFMulAdd #121925
Conversation
@llvm/pr-subscribers-backend-amdgpu Author: Chinmay Deshpande (chinmaydd) ChangesPatch is 22.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/121925.diff 1 Files Affected:
diff --git a/llvm/test/CodeGen/AMDGPU/prevent-fmul-hoist-ir.ll b/llvm/test/CodeGen/AMDGPU/prevent-fmul-hoist-ir.ll
new file mode 100644
index 00000000000000..6644488ef9375b
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/prevent-fmul-hoist-ir.ll
@@ -0,0 +1,447 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes='simplifycfg<hoist-common-insts>' -mtriple=amdgcn-- --fp-contract=fast -mcpu=gfx1030 < %s | FileCheck -check-prefix=GFX -check-prefix=FP-CONTRACT-FAST %s
+; RUN: opt -S -passes='simplifycfg<hoist-common-insts>' -mtriple=amdgcn-- --fp-contract=off --enable-unsafe-fp-math -mcpu=gfx1030 < %s | FileCheck -check-prefix=GFX -check-prefix=UNSAFE-FP-MATH %s
+; RUN: opt -S -passes='simplifycfg<hoist-common-insts>' -mtriple=amdgcn-- --fp-contract=off -mcpu=gfx1030 < %s | FileCheck -check-prefix=GFX -check-prefix=NO-UNSAFE-FP-MATH %s
+
+define double @is_profitable_f64_contract(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {
+; GFX-LABEL: define double @is_profitable_f64_contract(
+; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0:[0-9]+]] {
+; GFX-NEXT: [[ENTRY:.*:]]
+; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8
+; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00
+; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8
+; GFX-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8
+; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; GFX: [[COMMON_RET:.*]]:
+; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; GFX-NEXT: ret double [[COMMON_RET_OP]]
+; GFX: [[IF_THEN]]:
+; GFX-NEXT: [[MUL:%.*]] = fmul contract double [[X]], [[A_1]]
+; GFX-NEXT: [[ADD]] = fadd contract double 1.000000e+00, [[MUL]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+; GFX: [[IF_ELSE]]:
+; GFX-NEXT: [[MUL1:%.*]] = fmul contract double [[X]], [[A_1]]
+; GFX-NEXT: [[SUB]] = fsub contract double [[MUL1]], [[Y]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %y = load double, ptr %ptr_y, align 8
+ %cmp = fcmp oeq double %y, 0.000000e+00
+ %x = load double, ptr %ptr_x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %a_1 = load double, ptr %ptr_a, align 8
+ %mul = fmul contract double %x, %a_1
+ %add = fadd contract double 1.000000e+00, %mul
+ ret double %add
+
+if.else: ; preds = %entry
+ %a_2 = load double, ptr %ptr_a, align 8
+ %mul1 = fmul contract double %x, %a_2
+ %sub = fsub contract double %mul1, %y
+ ret double %sub
+}
+
+define double @is_profitable_f64_modifiers(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {
+; GFX-LABEL: define double @is_profitable_f64_modifiers(
+; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {
+; GFX-NEXT: [[ENTRY:.*:]]
+; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8
+; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00
+; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8
+; GFX-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8
+; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; GFX: [[COMMON_RET:.*]]:
+; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[FNEG:%.*]], %[[IF_THEN]] ], [ [[FABS:%.*]], %[[IF_ELSE]] ]
+; GFX-NEXT: ret double [[COMMON_RET_OP]]
+; GFX: [[IF_THEN]]:
+; GFX-NEXT: [[MUL:%.*]] = fmul contract double [[X]], [[A_1]]
+; GFX-NEXT: [[ADD:%.*]] = fadd contract double 1.000000e+00, [[MUL]]
+; GFX-NEXT: [[FNEG]] = fneg double [[ADD]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+; GFX: [[IF_ELSE]]:
+; GFX-NEXT: [[MUL1:%.*]] = fmul contract double [[X]], [[A_1]]
+; GFX-NEXT: [[SUB:%.*]] = fsub contract double [[MUL1]], [[Y]]
+; GFX-NEXT: [[FABS]] = call double @llvm.fabs.f64(double [[SUB]])
+; GFX-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %y = load double, ptr %ptr_y, align 8
+ %cmp = fcmp oeq double %y, 0.000000e+00
+ %x = load double, ptr %ptr_x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %a_1 = load double, ptr %ptr_a, align 8
+ %mul = fmul contract double %x, %a_1
+ %add = fadd contract double 1.000000e+00, %mul
+ %fneg = fneg double %add
+ ret double %fneg
+
+if.else: ; preds = %entry
+ %a_2 = load double, ptr %ptr_a, align 8
+ %mul1 = fmul contract double %x, %a_2
+ %sub = fsub contract double %mul1, %y
+ %fabs = call double @llvm.fabs.f64(double %sub)
+ ret double %fabs
+}
+
+define float @is_profitable_f32(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {
+; GFX-LABEL: define float @is_profitable_f32(
+; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {
+; GFX-NEXT: [[ENTRY:.*:]]
+; GFX-NEXT: [[Y:%.*]] = load float, ptr [[PTR_Y]], align 8
+; GFX-NEXT: [[CMP:%.*]] = fcmp oeq float [[Y]], 0.000000e+00
+; GFX-NEXT: [[X:%.*]] = load float, ptr [[PTR_X]], align 8
+; GFX-NEXT: [[A_1:%.*]] = load float, ptr [[PTR_A]], align 8
+; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; GFX: [[COMMON_RET:.*]]:
+; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi float [ [[MUL:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; GFX-NEXT: ret float [[COMMON_RET_OP]]
+; GFX: [[IF_THEN]]:
+; GFX-NEXT: [[MUL]] = fmul contract float [[X]], [[A_1]]
+; GFX-NEXT: [[ADD:%.*]] = fadd contract float 1.000000e+00, [[MUL]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+; GFX: [[IF_ELSE]]:
+; GFX-NEXT: [[MUL1:%.*]] = fmul contract float [[X]], [[A_1]]
+; GFX-NEXT: [[SUB]] = fsub contract float [[MUL1]], [[Y]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %y = load float, ptr %ptr_y, align 8
+ %cmp = fcmp oeq float %y, 0.000000e+00
+ %x = load float, ptr %ptr_x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+
+if.then: ; preds = %entry
+ %a_1 = load float, ptr %ptr_a, align 8
+ %mul = fmul contract float %x, %a_1
+ %add = fadd contract float 1.000000e+00, %mul
+ ret float %mul
+
+if.else: ; preds = %entry
+ %a_2 = load float, ptr %ptr_a, align 8
+ %mul1 = fmul contract float %x, %a_2
+ %sub = fsub contract float %mul1, %y
+ ret float %sub
+}
+
+define half @is_profitable_f16_preserve(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {
+; GFX-LABEL: define half @is_profitable_f16_preserve(
+; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {
+; GFX-NEXT: [[ENTRY:.*:]]
+; GFX-NEXT: [[Y:%.*]] = load half, ptr [[PTR_Y]], align 8
+; GFX-NEXT: [[CMP:%.*]] = fcmp oeq half [[Y]], 0xH0000
+; GFX-NEXT: [[X:%.*]] = load half, ptr [[PTR_X]], align 8
+; GFX-NEXT: [[A_1:%.*]] = load half, ptr [[PTR_A]], align 8
+; GFX-NEXT: [[MUL:%.*]] = fmul contract half [[X]], [[A_1]]
+; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; GFX: [[COMMON_RET:.*]]:
+; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi half [ [[MUL]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; GFX-NEXT: ret half [[COMMON_RET_OP]]
+; GFX: [[IF_THEN]]:
+; GFX-NEXT: [[ADD:%.*]] = fadd contract half [[Y]], [[MUL]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+; GFX: [[IF_ELSE]]:
+; GFX-NEXT: [[SUB]] = fsub contract half [[MUL]], [[Y]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %y = load half, ptr %ptr_y, align 8
+ %cmp = fcmp oeq half %y, 0.000000e+00
+ %x = load half, ptr %ptr_x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %a_1 = load half, ptr %ptr_a, align 8
+ %mul = fmul contract half %x, %a_1
+ %add = fadd contract half %y, %mul
+ ret half %mul
+
+if.else: ; preds = %entry
+ %a_2 = load half, ptr %ptr_a, align 8
+ %mul1 = fmul contract half %x, %a_2
+ %sub = fsub contract half %mul1, %y
+ ret half %sub
+}
+
+define half @is_profitable_f16_ieee(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #1 {
+; GFX-LABEL: define half @is_profitable_f16_ieee(
+; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR1:[0-9]+]] {
+; GFX-NEXT: [[ENTRY:.*:]]
+; GFX-NEXT: [[Y:%.*]] = load half, ptr [[PTR_Y]], align 8
+; GFX-NEXT: [[CMP:%.*]] = fcmp oeq half [[Y]], 0xH0000
+; GFX-NEXT: [[X:%.*]] = load half, ptr [[PTR_X]], align 8
+; GFX-NEXT: [[A_1:%.*]] = load half, ptr [[PTR_A]], align 8
+; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; GFX: [[COMMON_RET:.*]]:
+; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi half [ [[MUL:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; GFX-NEXT: ret half [[COMMON_RET_OP]]
+; GFX: [[IF_THEN]]:
+; GFX-NEXT: [[MUL]] = fmul contract half [[X]], [[A_1]]
+; GFX-NEXT: [[ADD:%.*]] = fadd contract half [[Y]], [[MUL]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+; GFX: [[IF_ELSE]]:
+; GFX-NEXT: [[MUL1:%.*]] = fmul contract half [[X]], [[A_1]]
+; GFX-NEXT: [[SUB]] = fsub contract half [[MUL1]], [[Y]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %y = load half, ptr %ptr_y, align 8
+ %cmp = fcmp oeq half %y, 0.000000e+00
+ %x = load half, ptr %ptr_x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %a_1 = load half, ptr %ptr_a, align 8
+ %mul = fmul contract half %x, %a_1
+ %add = fadd contract half %y, %mul
+ ret half %mul
+
+if.else: ; preds = %entry
+ %a_2 = load half, ptr %ptr_a, align 8
+ %mul1 = fmul contract half %x, %a_2
+ %sub = fsub contract half %mul1, %y
+ ret half %sub
+}
+
+define bfloat @is_profitable_bfloat_preserve(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {
+; GFX-LABEL: define bfloat @is_profitable_bfloat_preserve(
+; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {
+; GFX-NEXT: [[ENTRY:.*:]]
+; GFX-NEXT: [[Y:%.*]] = load bfloat, ptr [[PTR_Y]], align 8
+; GFX-NEXT: [[CMP:%.*]] = fcmp oeq bfloat [[Y]], 0xR0000
+; GFX-NEXT: [[X:%.*]] = load bfloat, ptr [[PTR_X]], align 8
+; GFX-NEXT: [[A_1:%.*]] = load bfloat, ptr [[PTR_A]], align 8
+; GFX-NEXT: [[MUL:%.*]] = fmul contract bfloat [[X]], [[A_1]]
+; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; GFX: [[COMMON_RET:.*]]:
+; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi bfloat [ [[MUL]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; GFX-NEXT: ret bfloat [[COMMON_RET_OP]]
+; GFX: [[IF_THEN]]:
+; GFX-NEXT: [[ADD:%.*]] = fadd contract bfloat 0xR3F80, [[MUL]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+; GFX: [[IF_ELSE]]:
+; GFX-NEXT: [[SUB]] = fsub contract bfloat [[MUL]], [[Y]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %y = load bfloat, ptr %ptr_y, align 8
+ %cmp = fcmp oeq bfloat %y, 0.000000e+00
+ %x = load bfloat, ptr %ptr_x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %a_1 = load bfloat, ptr %ptr_a, align 8
+ %mul = fmul contract bfloat %x, %a_1
+ %add = fadd contract bfloat 1.000000e+00, %mul
+ ret bfloat %mul
+
+if.else: ; preds = %entry
+ %a_2 = load bfloat, ptr %ptr_a, align 8
+ %mul1 = fmul contract bfloat %x, %a_2
+ %sub = fsub contract bfloat %mul1, %y
+ ret bfloat %sub
+}
+
+define bfloat @is_profitable_bfloat_ieee(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #1 {
+; GFX-LABEL: define bfloat @is_profitable_bfloat_ieee(
+; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR1]] {
+; GFX-NEXT: [[ENTRY:.*:]]
+; GFX-NEXT: [[Y:%.*]] = load bfloat, ptr [[PTR_Y]], align 8
+; GFX-NEXT: [[CMP:%.*]] = fcmp oeq bfloat [[Y]], 0xR0000
+; GFX-NEXT: [[X:%.*]] = load bfloat, ptr [[PTR_X]], align 8
+; GFX-NEXT: [[A_1:%.*]] = load bfloat, ptr [[PTR_A]], align 8
+; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; GFX: [[COMMON_RET:.*]]:
+; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi bfloat [ [[MUL:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; GFX-NEXT: ret bfloat [[COMMON_RET_OP]]
+; GFX: [[IF_THEN]]:
+; GFX-NEXT: [[MUL]] = fmul contract bfloat [[X]], [[A_1]]
+; GFX-NEXT: [[ADD:%.*]] = fadd contract bfloat 0xR3F80, [[MUL]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+; GFX: [[IF_ELSE]]:
+; GFX-NEXT: [[MUL1:%.*]] = fmul contract bfloat [[X]], [[A_1]]
+; GFX-NEXT: [[SUB]] = fsub contract bfloat [[MUL1]], [[Y]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %y = load bfloat, ptr %ptr_y, align 8
+ %cmp = fcmp oeq bfloat %y, 0.000000e+00
+ %x = load bfloat, ptr %ptr_x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %a_1 = load bfloat, ptr %ptr_a, align 8
+ %mul = fmul contract bfloat %x, %a_1
+ %add = fadd contract bfloat 1.000000e+00, %mul
+ ret bfloat %mul
+
+if.else: ; preds = %entry
+ %a_2 = load bfloat, ptr %ptr_a, align 8
+ %mul1 = fmul contract bfloat %x, %a_2
+ %sub = fsub contract bfloat %mul1, %y
+ ret bfloat %sub
+}
+
+define double @is_profitable_constant(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #1 {
+; GFX-LABEL: define double @is_profitable_constant(
+; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR1]] {
+; GFX-NEXT: [[ENTRY:.*:]]
+; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8
+; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00
+; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8
+; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; GFX: [[COMMON_RET:.*]]:
+; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; GFX-NEXT: ret double [[COMMON_RET_OP]]
+; GFX: [[IF_THEN]]:
+; GFX-NEXT: [[MUL:%.*]] = fmul contract double 2.000000e+00, [[X]]
+; GFX-NEXT: [[ADD]] = fadd contract double 1.000000e+00, [[MUL]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+; GFX: [[IF_ELSE]]:
+; GFX-NEXT: [[MUL1:%.*]] = fmul contract double 3.000000e+00, [[X]]
+; GFX-NEXT: [[SUB]] = fsub contract double [[MUL1]], [[Y]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %y = load double, ptr %ptr_y, align 8
+ %cmp = fcmp oeq double %y, 0.000000e+00
+ %x = load double, ptr %ptr_x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %mul = fmul contract double 2.000000e+00, %x
+ %add = fadd contract double 1.000000e+00, %mul
+ ret double %add
+
+if.else: ; preds = %entry
+ %mul1 = fmul contract double 3.000000e+00, %x
+ %sub = fsub contract double %mul1, %y
+ ret double %sub
+}
+
+%vec_type = type <8 x double>
+@v1_ptr = external addrspace(3) global ptr
+@v2_ptr = external addrspace(3) global ptr
+
+define %vec_type @is_profitable_vector(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) {
+; GFX-LABEL: define <8 x double> @is_profitable_vector(
+; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR2:[0-9]+]] {
+; GFX-NEXT: [[ENTRY:.*:]]
+; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8
+; GFX-NEXT: [[X:%.*]] = load <8 x double>, ptr [[PTR_X]], align 8
+; GFX-NEXT: [[V1:%.*]] = load <8 x double>, ptr addrspace(3) @v1_ptr, align 64
+; GFX-NEXT: [[V2:%.*]] = load <8 x double>, ptr addrspace(3) @v2_ptr, align 64
+; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00
+; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; GFX: [[COMMON_RET:.*]]:
+; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi <8 x double> [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; GFX-NEXT: ret <8 x double> [[COMMON_RET_OP]]
+; GFX: [[IF_THEN]]:
+; GFX-NEXT: [[MUL:%.*]] = fmul contract <8 x double> [[V1]], [[X]]
+; GFX-NEXT: [[ADD]] = fadd contract <8 x double> [[V2]], [[MUL]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+; GFX: [[IF_ELSE]]:
+; GFX-NEXT: [[MUL1:%.*]] = fmul contract <8 x double> [[V1]], [[X]]
+; GFX-NEXT: [[SUB]] = fsub contract <8 x double> [[MUL1]], [[V2]]
+; GFX-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %y = load double, ptr %ptr_y, align 8
+ %x = load %vec_type, ptr %ptr_x, align 8
+ %v1 = load %vec_type, ptr addrspace(3) @v1_ptr
+ %v2 = load %vec_type, ptr addrspace(3) @v2_ptr
+ %cmp = fcmp oeq double %y, 0.000000e+00
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %mul = fmul contract %vec_type %v1, %x
+ %add = fadd contract %vec_type %v2, %mul
+ ret %vec_type %add
+
+if.else: ; preds = %entry
+ %mul1 = fmul contract %vec_type %v1, %x
+ %sub = fsub contract %vec_type %mul1, %v2
+ ret %vec_type %sub
+}
+
+define double @is_profitable_f64_nocontract(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {
+; FP-CONTRACT-FAST-LABEL: define double @is_profitable_f64_nocontract(
+; FP-CONTRACT-FAST-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {
+; FP-CONTRACT-FAST-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8
+; FP-CONTRACT-FAST-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00
+; FP-CONTRACT-FAST-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8
+; FP-CONTRACT-FAST-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8
+; FP-CONTRACT-FAST-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; FP-CONTRACT-FAST: [[COMMON_RET:.*]]:
+; FP-CONTRACT-FAST-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[PTR_ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; FP-CONTRACT-FAST-NEXT: ret double [[COMMON_RET_OP]]
+; FP-CONTRACT-FAST: [[IF_THEN]]:
+; FP-CONTRACT-FAST-NEXT: [[MUL:%.*]] = fmul double [[X]], [[A_1]]
+; FP-CONTRACT-FAST-NEXT: [[PTR_ADD]] = fadd double 1.000000e+00, [[MUL]]
+; FP-CONTRACT-FAST-NEXT: br label %[[COMMON_RET]]
+; FP-CONTRACT-FAST: [[IF_ELSE]]:
+; FP-CONTRACT-FAST-NEXT: [[MUL1:%.*]] = fmul double [[X]], [[A_1]]
+; FP-CONTRACT-FAST-NEXT: [[SUB]] = fsub double [[MUL1]], [[Y]]
+; FP-CONTRACT-FAST-NEXT: br label %[[COMMON_RET]]
+;
+; UNSAFE-FP-MATH-LABEL: define double @is_profitable_f64_nocontract(
+; UNSAFE-FP-MATH-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {
+; UNSAFE-FP-MATH-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8
+; UNSAFE-FP-MATH-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00
+; UNSAFE-FP-MATH-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8
+; UNSAFE-FP-MATH-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8
+; UNSAFE-FP-MATH-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; UNSAFE-FP-MATH: [[COMMON_RET:.*]]:
+; UNSAFE-FP-MATH-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[PTR_ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]
+; UNSAFE-FP-MATH-NEXT: ...
[truncated]
|
br i1 %cmp, label %if.then, label %if.else | ||
|
||
if.then: ; preds = %entry | ||
%mul = fmul contract %vec_type %v1, %x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use <8 x double>
directly?
Also the half vectors are the most interesting cases
bcf4ff8
to
097a2da
Compare
%a_1 = load double, ptr %ptr_a, align 8 | ||
%mul = fmul contract double %x, %a_1 | ||
%add = fadd contract double 1.000000e+00, %mul | ||
%fneg = fneg double %add |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this to be a useful test, the modifier would need to be separating the add and the mul, not the use of it. i.e. add (fneg (fmul x, y)), z)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. In that case, I will have to update the main PR to work through that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can handle the modifiers in a follow up, but still good to get the baseline test in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arsenm gentle ping
…ndFAdd Change-Id: I2bdf11d08ac659d6b14a021eadc5b86752112c73
097a2da
to
caa028a
Compare
Test failure is unrelated and was reverted here: ab5133b |
Pre-commit tests for #121465