ret float %div
}
-; (X/Y)/Z = > X/(Y*Z)
-define float @fdiv5(float %f1, float %f2, float %f3) {
-; CHECK-LABEL: @fdiv5(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[F2:%.*]], [[F3:%.*]]
-; CHECK-NEXT: [[T2:%.*]] = fdiv fast float [[F1:%.*]], [[TMP1]]
-; CHECK-NEXT: ret float [[T2]]
-;
- %t1 = fdiv float %f1, %f2
- %t2 = fdiv fast float %t1, %f3
- ret float %t2
-}
-
-; Z/(X/Y) = > (Z*Y)/X
-define float @fdiv6(float %f1, float %f2, float %f3) {
-; CHECK-LABEL: @fdiv6(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[F3:%.*]], [[F2:%.*]]
-; CHECK-NEXT: [[T2:%.*]] = fdiv fast float [[TMP1]], [[F1:%.*]]
-; CHECK-NEXT: ret float [[T2]]
-;
- %t1 = fdiv float %f1, %f2
- %t2 = fdiv fast float %f3, %t1
- ret float %t2
-}
-
; C1/(X*C2) => (C1/C2) / X
define float @fdiv7(float %x) {
; CHECK-LABEL: @fdiv7(
ret <2 x float> %div
}
-define float @test5(float %x, float %y, float %z) {
-; CHECK-LABEL: @test5(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[Y:%.*]], [[Z:%.*]]
+; (X / Y) / Z --> X / (Y * Z)
+
+define float @div_with_div_numerator(float %x, float %y, float %z) {
+; CHECK-LABEL: @div_with_div_numerator(
+; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[Y:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast float [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret float [[DIV2]]
;
- %div1 = fdiv fast float %x, %y
+ %div1 = fdiv float %x, %y
+ %div2 = fdiv fast float %div1, %z
+ ret float %div2
+}
+
+; Z / (X / Y) --> (Z * Y) / X
+
+define <2 x float> @div_with_div_denominator(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
+; CHECK-LABEL: @div_with_div_denominator(
+; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[Z:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast <2 x float> [[TMP1]], [[X:%.*]]
+; CHECK-NEXT: ret <2 x float> [[DIV2]]
+;
+ %div1 = fdiv <2 x float> %x, %y
+ %div2 = fdiv fast <2 x float> %z, %div1
+ ret <2 x float> %div2
+}
+
+; Don't create an extra multiply if we can't eliminate the first div.
+
+declare void @use_f32(float)
+
+define float @div_with_div_numerator_extra_use(float %x, float %y, float %z) {
+; CHECK-LABEL: @div_with_div_numerator_extra_use(
+; CHECK-NEXT: [[DIV1:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast float [[DIV1]], [[Z:%.*]]
+; CHECK-NEXT: call void @use_f32(float [[DIV1]])
+; CHECK-NEXT: ret float [[DIV2]]
+;
+ %div1 = fdiv float %x, %y
%div2 = fdiv fast float %div1, %z
+ call void @use_f32(float %div1)
ret float %div2
}
-define float @test6(float %x, float %y, float %z) {
-; CHECK-LABEL: @test6(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[Z:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast float [[TMP1]], [[X:%.*]]
+define float @div_with_div_denominator_extra_use(float %x, float %y, float %z) {
+; CHECK-LABEL: @div_with_div_denominator_extra_use(
+; CHECK-NEXT: [[DIV1:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast float [[Z:%.*]], [[DIV1]]
+; CHECK-NEXT: call void @use_f32(float [[DIV1]])
; CHECK-NEXT: ret float [[DIV2]]
;
- %div1 = fdiv fast float %x, %y
+ %div1 = fdiv float %x, %y
%div2 = fdiv fast float %z, %div1
+ call void @use_f32(float %div1)
ret float %div2
}