Skip to content

Commit 21f1b2d

Browse files
committed
[InstSimplify] fold fsub nnan with Inf operand
Similar to fbc2c8f, but if we have a non-canonical fsub with constant operand 1, then flip the sign of the Infinity: https://alive2.llvm.org/ce/z/vKWfhW If Infinity is operand 0, then the sign remains: https://alive2.llvm.org/ce/z/73d97C
1 parent 15b2702 commit 21f1b2d

File tree

3 files changed

+24
-15
lines changed

3 files changed

+24
-15
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5322,9 +5322,19 @@ simplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
53225322
if (!isDefaultFPEnvironment(ExBehavior, Rounding))
53235323
return nullptr;
53245324

5325-
// fsub nnan x, x ==> 0.0
5326-
if (FMF.noNaNs() && Op0 == Op1)
5327-
return Constant::getNullValue(Op0->getType());
5325+
if (FMF.noNaNs()) {
5326+
// fsub nnan x, x ==> 0.0
5327+
if (Op0 == Op1)
5328+
return Constant::getNullValue(Op0->getType());
5329+
5330+
// With nnan: {+/-}Inf - X --> {+/-}Inf
5331+
if (match(Op0, m_Inf()))
5332+
return Op0;
5333+
5334+
// With nnan: X - {+/-}Inf --> {-/+}Inf
5335+
if (match(Op1, m_Inf()))
5336+
return foldConstant(Instruction::FNeg, Op1, Q);
5337+
}
53285338

53295339
// Y - (Y - X) --> X
53305340
// (X + Y) - Y --> X

llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -861,40 +861,42 @@ define double @fadd_inf_op0(double %x) {
861861

862862
define double @fsub_nnan_inf_op0(double %x) {
863863
; CHECK-LABEL: @fsub_nnan_inf_op0(
864-
; CHECK-NEXT: [[R:%.*]] = fsub nnan double 0x7FF0000000000000, [[X:%.*]]
865-
; CHECK-NEXT: ret double [[R]]
864+
; CHECK-NEXT: ret double 0x7FF0000000000000
866865
;
867866
%r = fsub nnan double 0x7ff0000000000000, %x
868867
ret double %r
869868
}
870869

870+
; flip sign
871+
871872
define double @fsub_nnan_inf_op1(double %x) {
872873
; CHECK-LABEL: @fsub_nnan_inf_op1(
873-
; CHECK-NEXT: [[R:%.*]] = fsub nnan double [[X:%.*]], 0x7FF0000000000000
874-
; CHECK-NEXT: ret double [[R]]
874+
; CHECK-NEXT: ret double 0xFFF0000000000000
875875
;
876876
%r = fsub nnan double %x, 0x7ff0000000000000
877877
ret double %r
878878
}
879879

880880
define <2 x double> @fsub_nnan_neginf_op0(<2 x double> %x) {
881881
; CHECK-LABEL: @fsub_nnan_neginf_op0(
882-
; CHECK-NEXT: [[R:%.*]] = fsub nnan <2 x double> <double 0xFFF0000000000000, double poison>, [[X:%.*]]
883-
; CHECK-NEXT: ret <2 x double> [[R]]
882+
; CHECK-NEXT: ret <2 x double> <double 0xFFF0000000000000, double poison>
884883
;
885884
%r = fsub nnan <2 x double> <double 0xfff0000000000000, double poison>, %x
886885
ret <2 x double> %r
887886
}
888887

888+
; flip sign
889+
889890
define double @fsub_nnan_neginf_op1(double %x) {
890891
; CHECK-LABEL: @fsub_nnan_neginf_op1(
891-
; CHECK-NEXT: [[R:%.*]] = fsub nnan double [[X:%.*]], 0xFFF0000000000000
892-
; CHECK-NEXT: ret double [[R]]
892+
; CHECK-NEXT: ret double 0x7FF0000000000000
893893
;
894894
%r = fsub nnan double %x, 0xfff0000000000000
895895
ret double %r
896896
}
897897

898+
; negative test - requires nnan
899+
898900
define double @fsub_inf_op0(double %x) {
899901
; CHECK-LABEL: @fsub_inf_op0(
900902
; CHECK-NEXT: [[R:%.*]] = fsub double 0x7FF0000000000000, [[X:%.*]]

llvm/test/Transforms/InstSimplify/fp-undef-poison.ll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,9 @@ define double @fadd_ninf_inf_op1(double %x) {
275275
ret double %r
276276
}
277277

278-
; TODO: Should simplify to inf.
279-
280278
define double @fsub_nnan_inf_op0(double %x) {
281279
; CHECK-LABEL: @fsub_nnan_inf_op0(
282-
; CHECK-NEXT: [[R:%.*]] = fsub nnan double 0x7FF0000000000000, [[X:%.*]]
283-
; CHECK-NEXT: ret double [[R]]
280+
; CHECK-NEXT: ret double 0x7FF0000000000000
284281
;
285282
%r = fsub nnan double 0x7ff0000000000000, %x
286283
ret double %r

0 commit comments

Comments
 (0)