[InstCombine] add vector and vector undef tests for FP folds; NFC

llvm-svn: 329294
This commit is contained in:
Sanjay Patel
2018-04-05 15:07:35 +00:00
parent 131fb978b0
commit 2eaa2a43f8
3 changed files with 226 additions and 89 deletions

View File

@@ -1,10 +1,11 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -instcombine < %s | FileCheck %s
declare double @llvm.fabs.f64(double) nounwind readnone
declare double @llvm.fabs.f64(double) readnone
define i1 @test1(float %x, float %y) nounwind {
define i1 @test1(float %x, float %y) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float %x, %y
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%ext1 = fpext float %x to double
@@ -13,9 +14,9 @@ define i1 @test1(float %x, float %y) nounwind {
ret i1 %cmp
}
define i1 @test2(float %a) nounwind {
define i1 @test2(float %a) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float %a, 1.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 1.000000e+00
; CHECK-NEXT: ret i1 [[CMP]]
;
%ext = fpext float %a to double
@@ -23,9 +24,9 @@ define i1 @test2(float %a) nounwind {
ret i1 %cmp
}
define i1 @test3(float %a) nounwind {
define i1 @test3(float %a) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[EXT:%.*]] = fpext float %a to double
; CHECK-NEXT: [[EXT:%.*]] = fpext float [[A:%.*]] to double
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x3FF0000000000001
; CHECK-NEXT: ret i1 [[CMP]]
;
@@ -34,9 +35,9 @@ define i1 @test3(float %a) nounwind {
ret i1 %cmp
}
define i1 @test4(float %a) nounwind {
define i1 @test4(float %a) {
; CHECK-LABEL: @test4(
; CHECK-NEXT: [[EXT:%.*]] = fpext float %a to double
; CHECK-NEXT: [[EXT:%.*]] = fpext float [[A:%.*]] to double
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x36A0000000000000
; CHECK-NEXT: ret i1 [[CMP]]
;
@@ -45,30 +46,75 @@ define i1 @test4(float %a) nounwind {
ret i1 %cmp
}
define i1 @test5(float %a) nounwind {
; CHECK-LABEL: @test5(
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float %a, -1.000000e+00
define i1 @fneg_constant_swap_pred(float %x) {
; CHECK-LABEL: @fneg_constant_swap_pred(
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00
; CHECK-NEXT: ret i1 [[CMP]]
;
%neg = fsub float -0.000000e+00, %a
%cmp = fcmp ogt float %neg, 1.000000e+00
%neg = fsub float -0.0, %x
%cmp = fcmp ogt float %neg, 1.0
ret i1 %cmp
}
define i1 @test6(float %x, float %y) nounwind {
; CHECK-LABEL: @test6(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float %x, %y
define <2 x i1> @fneg_constant_swap_pred_vec(<2 x float> %x) {
; CHECK-LABEL: @fneg_constant_swap_pred_vec(
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%neg = fsub <2 x float> <float -0.0, float -0.0>, %x
%cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
ret <2 x i1> %cmp
}
define <2 x i1> @fneg_constant_swap_pred_vec_undef(<2 x float> %x) {
; CHECK-LABEL: @fneg_constant_swap_pred_vec_undef(
; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[NEG]], <float 1.000000e+00, float 2.000000e+00>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%neg = fsub <2 x float> <float undef, float -0.0>, %x
%cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
ret <2 x i1> %cmp
}
define i1 @fneg_fneg_swap_pred(float %x, float %y) {
; CHECK-LABEL: @fneg_fneg_swap_pred(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%neg1 = fsub float -0.000000e+00, %x
%neg2 = fsub float -0.000000e+00, %y
%neg1 = fsub float -0.0, %x
%neg2 = fsub float -0.0, %y
%cmp = fcmp olt float %neg1, %neg2
ret i1 %cmp
}
define i1 @test7(float %x) nounwind readnone ssp noredzone {
define <2 x i1> @fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @fneg_fneg_swap_pred_vec(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x
%neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y
%cmp = fcmp olt <2 x float> %neg1, %neg2
ret <2 x i1> %cmp
}
define <2 x i1> @fneg_fneg_swap_pred_vec_undef(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @fneg_fneg_swap_pred_vec_undef(
; CHECK-NEXT: [[NEG1:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X:%.*]]
; CHECK-NEXT: [[NEG2:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[Y:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[NEG1]], [[NEG2]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%neg1 = fsub <2 x float> <float -0.0, float undef>, %x
%neg2 = fsub <2 x float> <float undef, float -0.0>, %y
%cmp = fcmp olt <2 x float> %neg1, %neg2
ret <2 x i1> %cmp
}
define i1 @test7(float %x) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float %x, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00
; CHECK-NEXT: ret i1 [[CMP]]
;
%ext = fpext float %x to ppc_fp128
@@ -76,9 +122,9 @@ define i1 @test7(float %x) nounwind readnone ssp noredzone {
ret i1 %cmp
}
define float @test8(float %x) nounwind readnone optsize ssp {
define float @test8(float %x) {
; CHECK-LABEL: @test8(
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float %x, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV2:%.*]] = uitofp i1 [[CMP]] to float
; CHECK-NEXT: ret float [[CONV2]]
;
@@ -90,212 +136,212 @@ define float @test8(float %x) nounwind readnone optsize ssp {
; Float comparison to zero shouldn't cast to double.
}
declare double @fabs(double) nounwind readnone
declare double @fabs(double) readnone
define i32 @test9(double %a) nounwind {
define i32 @test9(double %a) {
; CHECK-LABEL: @test9(
; CHECK-NEXT: ret i32 0
;
%call = tail call double @fabs(double %a) nounwind
%call = tail call double @fabs(double %a)
%cmp = fcmp olt double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test9_intrinsic(double %a) nounwind {
define i32 @test9_intrinsic(double %a) {
; CHECK-LABEL: @test9_intrinsic(
; CHECK-NEXT: ret i32 0
;
%call = tail call double @llvm.fabs.f64(double %a) nounwind
%call = tail call double @llvm.fabs.f64(double %a)
%cmp = fcmp olt double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test10(double %a) nounwind {
define i32 @test10(double %a) {
; CHECK-LABEL: @test10(
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @fabs(double %a) nounwind
%call = tail call double @fabs(double %a)
%cmp = fcmp ole double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test10_intrinsic(double %a) nounwind {
define i32 @test10_intrinsic(double %a) {
; CHECK-LABEL: @test10_intrinsic(
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @llvm.fabs.f64(double %a) nounwind
%call = tail call double @llvm.fabs.f64(double %a)
%cmp = fcmp ole double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test11(double %a) nounwind {
define i32 @test11(double %a) {
; CHECK-LABEL: @test11(
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @fabs(double %a) nounwind
%call = tail call double @fabs(double %a)
%cmp = fcmp ogt double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test11_intrinsic(double %a) nounwind {
define i32 @test11_intrinsic(double %a) {
; CHECK-LABEL: @test11_intrinsic(
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @llvm.fabs.f64(double %a) nounwind
%call = tail call double @llvm.fabs.f64(double %a)
%cmp = fcmp ogt double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test12(double %a) nounwind {
define i32 @test12(double %a) {
; CHECK-LABEL: @test12(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ord double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp ord double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @fabs(double %a) nounwind
%call = tail call double @fabs(double %a)
%cmp = fcmp oge double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test12_intrinsic(double %a) nounwind {
define i32 @test12_intrinsic(double %a) {
; CHECK-LABEL: @test12_intrinsic(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ord double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp ord double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @llvm.fabs.f64(double %a) nounwind
%call = tail call double @llvm.fabs.f64(double %a)
%cmp = fcmp oge double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test13(double %a) nounwind {
define i32 @test13(double %a) {
; CHECK-LABEL: @test13(
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @fabs(double %a) nounwind
%call = tail call double @fabs(double %a)
%cmp = fcmp une double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test13_intrinsic(double %a) nounwind {
define i32 @test13_intrinsic(double %a) {
; CHECK-LABEL: @test13_intrinsic(
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @llvm.fabs.f64(double %a) nounwind
%call = tail call double @llvm.fabs.f64(double %a)
%cmp = fcmp une double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test14(double %a) nounwind {
define i32 @test14(double %a) {
; CHECK-LABEL: @test14(
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @fabs(double %a) nounwind
%call = tail call double @fabs(double %a)
%cmp = fcmp oeq double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test14_intrinsic(double %a) nounwind {
define i32 @test14_intrinsic(double %a) {
; CHECK-LABEL: @test14_intrinsic(
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @llvm.fabs.f64(double %a) nounwind
%call = tail call double @llvm.fabs.f64(double %a)
%cmp = fcmp oeq double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test15(double %a) nounwind {
define i32 @test15(double %a) {
; CHECK-LABEL: @test15(
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @fabs(double %a) nounwind
%call = tail call double @fabs(double %a)
%cmp = fcmp one double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test15_intrinsic(double %a) nounwind {
define i32 @test15_intrinsic(double %a) {
; CHECK-LABEL: @test15_intrinsic(
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @llvm.fabs.f64(double %a) nounwind
%call = tail call double @llvm.fabs.f64(double %a)
%cmp = fcmp one double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test16(double %a) nounwind {
define i32 @test16(double %a) {
; CHECK-LABEL: @test16(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @fabs(double %a) nounwind
%call = tail call double @fabs(double %a)
%cmp = fcmp ueq double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @test16_intrinsic(double %a) nounwind {
define i32 @test16_intrinsic(double %a) {
; CHECK-LABEL: @test16_intrinsic(
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double %a, 0.000000e+00
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double @llvm.fabs.f64(double %a) nounwind
%call = tail call double @llvm.fabs.f64(double %a)
%cmp = fcmp ueq double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
; Don't crash.
define i32 @test17(double %a, double (double)* %p) nounwind {
define i32 @test17(double %a, double (double)* %p) {
; CHECK-LABEL: @test17(
; CHECK-NEXT: [[CALL:%.*]] = tail call double %p(double %a) #1
; CHECK-NEXT: [[CALL:%.*]] = tail call double [[P:%.*]](double [[A:%.*]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[CALL]], 0.000000e+00
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
%call = tail call double %p(double %a) nounwind
%call = tail call double %p(double %a)
%cmp = fcmp ueq double %call, 0.000000e+00
%conv = zext i1 %cmp to i32
ret i32 %conv
}
; Can fold fcmp with undef on one side by choosing NaN for the undef
define i32 @test18_undef_unordered(float %a) nounwind {
define i32 @test18_undef_unordered(float %a) {
; CHECK-LABEL: @test18_undef_unordered(
; CHECK-NEXT: ret i32 1
;
@@ -304,7 +350,7 @@ define i32 @test18_undef_unordered(float %a) nounwind {
ret i32 %conv
}
; Can fold fcmp with undef on one side by choosing NaN for the undef
define i32 @test18_undef_ordered(float %a) nounwind {
define i32 @test18_undef_ordered(float %a) {
; CHECK-LABEL: @test18_undef_ordered(
; CHECK-NEXT: ret i32 0
;
@@ -318,7 +364,7 @@ define i32 @test18_undef_ordered(float %a) nounwind {
; fcmp o_pred undef, undef -> false
; because whatever you choose for the first undef
; you can choose NaN for the other undef
define i1 @test19_undef_unordered() nounwind {
define i1 @test19_undef_unordered() {
; CHECK-LABEL: @test19_undef_unordered(
; CHECK-NEXT: ret i1 true
;
@@ -326,7 +372,7 @@ define i1 @test19_undef_unordered() nounwind {
ret i1 %cmp
}
define i1 @test19_undef_ordered() nounwind {
define i1 @test19_undef_ordered() {
; CHECK-LABEL: @test19_undef_ordered(
; CHECK-NEXT: ret i1 false
;

View File

@@ -19,6 +19,30 @@ define float @fma_fneg_x_fneg_y(float %x, float %y, float %z) {
ret float %fma
}
define <2 x float> @fma_fneg_x_fneg_y_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
; CHECK-LABEL: @fma_fneg_x_fneg_y_vec(
; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
; CHECK-NEXT: ret <2 x float> [[FMA]]
;
%xn = fsub <2 x float> <float -0.0, float -0.0>, %x
%yn = fsub <2 x float> <float -0.0, float -0.0>, %y
%fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)
ret <2 x float> %fma
}
define <2 x float> @fma_fneg_x_fneg_y_vec_undef(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
; CHECK-LABEL: @fma_fneg_x_fneg_y_vec_undef(
; CHECK-NEXT: [[XN:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X:%.*]]
; CHECK-NEXT: [[YN:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[Y:%.*]]
; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[XN]], <2 x float> [[YN]], <2 x float> [[Z:%.*]])
; CHECK-NEXT: ret <2 x float> [[FMA]]
;
%xn = fsub <2 x float> <float -0.0, float undef>, %x
%yn = fsub <2 x float> <float undef, float -0.0>, %y
%fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)
ret <2 x float> %fma
}
define float @fma_fneg_x_fneg_y_fast(float %x, float %y, float %z) {
; CHECK-LABEL: @fma_fneg_x_fneg_y_fast(
; CHECK-NEXT: [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])

View File

@@ -7,18 +7,39 @@ define float @neg_constant(float %x) {
; CHECK-NEXT: [[MUL:%.*]] = fmul ninf float [[X:%.*]], -2.000000e+01
; CHECK-NEXT: ret float [[MUL]]
;
%sub = fsub float -0.000000e+00, %x
%sub = fsub float -0.0, %x
%mul = fmul ninf float %sub, 2.0e+1
ret float %mul
}
define <2 x float> @neg_constant_vec(<2 x float> %x) {
; CHECK-LABEL: @neg_constant_vec(
; CHECK-NEXT: [[MUL:%.*]] = fmul ninf <2 x float> [[X:%.*]], <float -2.000000e+00, float -3.000000e+00>
; CHECK-NEXT: ret <2 x float> [[MUL]]
;
%sub = fsub <2 x float> <float -0.0, float -0.0>, %x
%mul = fmul ninf <2 x float> %sub, <float 2.0, float 3.0>
ret <2 x float> %mul
}
define <2 x float> @neg_constant_vec_undef(<2 x float> %x) {
; CHECK-LABEL: @neg_constant_vec_undef(
; CHECK-NEXT: [[SUB:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]]
; CHECK-NEXT: [[MUL:%.*]] = fmul ninf <2 x float> [[SUB]], <float 2.000000e+00, float 3.000000e+00>
; CHECK-NEXT: ret <2 x float> [[MUL]]
;
%sub = fsub <2 x float> <float undef, float -0.0>, %x
%mul = fmul ninf <2 x float> %sub, <float 2.0, float 3.0>
ret <2 x float> %mul
}
; (0.0 - X) * C => X * -C
define float @neg_nsz_constant(float %x) {
; CHECK-LABEL: @neg_nsz_constant(
; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[X:%.*]], -2.000000e+01
; CHECK-NEXT: ret float [[MUL]]
;
%sub = fsub nsz float 0.000000e+00, %x
%sub = fsub nsz float 0.0, %x
%mul = fmul nnan float %sub, 2.0e+1
ret float %mul
}
@@ -29,20 +50,44 @@ define float @neg_neg(float %x, float %y) {
; CHECK-NEXT: [[MUL:%.*]] = fmul arcp float [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret float [[MUL]]
;
%sub1 = fsub float -0.000000e+00, %x
%sub2 = fsub float -0.000000e+00, %y
%sub1 = fsub float -0.0, %x
%sub2 = fsub float -0.0, %y
%mul = fmul arcp float %sub1, %sub2
ret float %mul
}
define <2 x float> @neg_neg_vec(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @neg_neg_vec(
; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x float> [[MUL]]
;
%sub1 = fsub <2 x float> <float -0.0, float -0.0>, %x
%sub2 = fsub <2 x float> <float -0.0, float -0.0>, %y
%mul = fmul arcp <2 x float> %sub1, %sub2
ret <2 x float> %mul
}
define <2 x float> @neg_neg_vec_undef(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @neg_neg_vec_undef(
; CHECK-NEXT: [[SUB1:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X:%.*]]
; CHECK-NEXT: [[SUB2:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[Y:%.*]]
; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[SUB1]], [[SUB2]]
; CHECK-NEXT: ret <2 x float> [[MUL]]
;
%sub1 = fsub <2 x float> <float -0.0, float undef>, %x
%sub2 = fsub <2 x float> <float undef, float -0.0>, %y
%mul = fmul arcp <2 x float> %sub1, %sub2
ret <2 x float> %mul
}
; (0.0 - X) * (0.0 - Y) => X * Y
define float @neg_neg_nsz(float %x, float %y) {
; CHECK-LABEL: @neg_neg_nsz(
; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret float [[MUL]]
;
%sub1 = fsub nsz float 0.000000e+00, %x
%sub2 = fsub nsz float 0.000000e+00, %y
%sub1 = fsub nsz float 0.0, %x
%sub2 = fsub nsz float 0.0, %y
%mul = fmul afn float %sub1, %sub2
ret float %mul
}
@@ -58,8 +103,8 @@ define float @neg_neg_multi_use(float %x, float %y) {
; CHECK-NEXT: call void @use_f32(float [[NY]])
; CHECK-NEXT: ret float [[MUL]]
;
%nx = fsub float -0.000000e+00, %x
%ny = fsub float -0.000000e+00, %y
%nx = fsub float -0.0, %x
%ny = fsub float -0.0, %y
%mul = fmul afn float %nx, %ny
call void @use_f32(float %nx)
call void @use_f32(float %ny)
@@ -73,11 +118,33 @@ define float @neg_sink(float %x, float %y) {
; CHECK-NEXT: [[MUL:%.*]] = fsub float -0.000000e+00, [[TMP1]]
; CHECK-NEXT: ret float [[MUL]]
;
%sub1 = fsub float -0.000000e+00, %x
%mul = fmul float %sub1, %y
%sub = fsub float -0.0, %x
%mul = fmul float %sub, %y
ret float %mul
}
define <2 x float> @neg_sink_vec(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @neg_sink_vec(
; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[MUL:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[TMP1]]
; CHECK-NEXT: ret <2 x float> [[MUL]]
;
%sub = fsub <2 x float> <float -0.0, float -0.0>, %x
%mul = fmul <2 x float> %sub, %y
ret <2 x float> %mul
}
define <2 x float> @neg_sink_vec_undef(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @neg_sink_vec_undef(
; CHECK-NEXT: [[SUB:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]]
; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[SUB]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x float> [[MUL]]
;
%sub = fsub <2 x float> <float undef, float -0.0>, %x
%mul = fmul <2 x float> %sub, %y
ret <2 x float> %mul
}
; (0.0 - X) * Y => 0.0 - (X * Y)
define float @neg_sink_nsz(float %x, float %y) {
; CHECK-LABEL: @neg_sink_nsz(
@@ -85,7 +152,7 @@ define float @neg_sink_nsz(float %x, float %y) {
; CHECK-NEXT: [[MUL:%.*]] = fsub float -0.000000e+00, [[TMP1]]
; CHECK-NEXT: ret float [[MUL]]
;
%sub1 = fsub nsz float 0.000000e+00, %x
%sub1 = fsub nsz float 0.0, %x
%mul = fmul float %sub1, %y
ret float %mul
}
@@ -99,7 +166,7 @@ define float @neg_sink_multi_use(float %x, float %y) {
; CHECK-NEXT: [[MUL2:%.*]] = fmul float [[MUL]], [[SUB1]]
; CHECK-NEXT: ret float [[MUL2]]
;
%sub1 = fsub float -0.000000e+00, %x
%sub1 = fsub float -0.0, %x
%mul = fmul float %sub1, %y
%mul2 = fmul float %mul, %sub1
ret float %mul2