@@ -8,6 +8,8 @@ declare float @llvm.exp.f32(float) nounwind readnone
8
8
declare <2 x half > @llvm.exp.v2f16 (<2 x half >) nounwind readnone
9
9
declare float @llvm.exp2.f32 (float ) nounwind readnone
10
10
declare <2 x half > @llvm.exp2.v2f16 (<2 x half >) nounwind readnone
11
+ declare float @llvm.powi.f32 (float , i32 ) nounwind readnone
12
+ declare <2 x half > @llvm.powi.v2f16 (<2 x half >, i32 ) nounwind readnone
11
13
12
14
define float @exact_inverse (float %x ) {
13
15
; CHECK-LABEL: @exact_inverse(
@@ -860,3 +862,68 @@ define <2 x half> @exp2_recip(<2 x half> %x, <2 x half> %y) {
860
862
%r = fdiv reassoc arcp ninf <2 x half > <half 1 .0 , half 1 .0 >, %p
861
863
ret <2 x half > %r
862
864
}
865
+
866
+ define float @powi_divisor (float %x , i32 %y , float %z ) {
867
+ ; CHECK-LABEL: @powi_divisor(
868
+ ; CHECK-NEXT: [[P:%.*]] = call float @llvm.powi.f32(float [[X:%.*]], i32 [[Y:%.*]])
869
+ ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc ninf arcp float [[Z:%.*]], [[P]]
870
+ ; CHECK-NEXT: ret float [[R]]
871
+ ;
872
+ %p = call float @llvm.powi.f32 (float %x , i32 %y )
873
+ %r = fdiv reassoc arcp ninf float %z , %p
874
+ ret float %r
875
+ }
876
+
877
+ ; Negative test - don't create an extra pow
878
+
879
+ define float @powi_divisor_extra_use (float %x , i32 %y , float %z ) {
880
+ ; CHECK-LABEL: @powi_divisor_extra_use(
881
+ ; CHECK-NEXT: [[P:%.*]] = call float @llvm.powi.f32(float [[X:%.*]], i32 [[Y:%.*]])
882
+ ; CHECK-NEXT: call void @use_f32(float [[P]])
883
+ ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc ninf arcp float [[Z:%.*]], [[P]]
884
+ ; CHECK-NEXT: ret float [[R]]
885
+ ;
886
+ %p = call float @llvm.powi.f32 (float %x , i32 %y )
887
+ call void @use_f32 (float %p )
888
+ %r = fdiv reassoc arcp ninf float %z , %p
889
+ ret float %r
890
+ }
891
+
892
+ ; Negative test - must have reassoc+arcp+ninf
893
+
894
+ define float @powi_divisor_not_enough_fmf (float %x , i32 %y , float %z ) {
895
+ ; CHECK-LABEL: @powi_divisor_not_enough_fmf(
896
+ ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.powi.f32(float [[X:%.*]], i32 [[Y:%.*]])
897
+ ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc ninf float [[Z:%.*]], [[P]]
898
+ ; CHECK-NEXT: ret float [[R]]
899
+ ;
900
+ %p = call fast float @llvm.powi.f32 (float %x , i32 %y )
901
+ %r = fdiv reassoc ninf float %z , %p
902
+ ret float %r
903
+ }
904
+
905
+ ; Negative test - must have reassoc+arcp+ninf
906
+
907
+ define float @powi_divisor_not_enough_fmf2 (float %x , i32 %y , float %z ) {
908
+ ; CHECK-LABEL: @powi_divisor_not_enough_fmf2(
909
+ ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.powi.f32(float [[X:%.*]], i32 [[Y:%.*]])
910
+ ; CHECK-NEXT: [[R:%.*]] = fdiv ninf arcp float [[Z:%.*]], [[P]]
911
+ ; CHECK-NEXT: ret float [[R]]
912
+ ;
913
+ %p = call fast float @llvm.powi.f32 (float %x , i32 %y )
914
+ %r = fdiv arcp ninf float %z , %p
915
+ ret float %r
916
+ }
917
+
918
+ ; Special-case - reciprocal does not require extra fmul
919
+
920
+ define <2 x half > @powi_recip (<2 x half > %x , i32 %y ) {
921
+ ; CHECK-LABEL: @powi_recip(
922
+ ; CHECK-NEXT: [[P:%.*]] = call <2 x half> @llvm.powi.v2f16(<2 x half> [[X:%.*]], i32 [[Y:%.*]])
923
+ ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc nnan ninf arcp <2 x half> <half 0xH3C00, half 0xH3C00>, [[P]]
924
+ ; CHECK-NEXT: ret <2 x half> [[R]]
925
+ ;
926
+ %p = call <2 x half > @llvm.powi.v2f16 (<2 x half > %x , i32 %y )
927
+ %r = fdiv reassoc arcp nnan ninf <2 x half > <half 1 .0 , half 1 .0 >, %p
928
+ ret <2 x half > %r
929
+ }
0 commit comments