Skip to content

Commit a0029be

Browse files
committed
Make sure to propagate NaN payloads when folding
1 parent e94017f commit a0029be

File tree

5 files changed

+111
-3
lines changed

5 files changed

+111
-3
lines changed

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3228,11 +3228,22 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
32283228
case LibFunc_nexttoward:
32293229
case LibFunc_nexttowardf:
32303230
if (TLI->has(Func)) {
3231-
if (Op1V.isNaN() || Op2V.isNaN()) {
3232-
return ConstantFP::get(Ty->getContext(),
3233-
APFloat::getNaN(Ty->getFltSemantics()));
3231+
// Make sure to propagate NaN payloads.
3232+
if (Op1V.isNaN()) {
3233+
return ConstantFP::get(Ty->getContext(), Op1V);
3234+
}
3235+
if (Op2V.isNaN()) {
3236+
// Payload propagation might not make sense if the second argument's
3237+
// type is wider than the return value. We'll give up in the latter
3238+
// case.
3239+
bool SemEqual = &Op2V.getSemantics() == &Ty->getFltSemantics();
3240+
APFloat Ret = SemEqual ? Op2V : APFloat::getNaN(Ty->getFltSemantics());
3241+
return ConstantFP::get(Ty->getContext(), Ret);
32343242
}
32353243

3244+
// The two arguments of nexttoward can have differing semantics.
3245+
// We need to convert both arguments to the same semantics so
3246+
// we can do comparisons.
32363247
APFloat PromotedOp1V = Op1V.getPromoted(APFloat::IEEEquad());
32373248
APFloat PromotedOp2V = Op2V.getPromoted(APFloat::IEEEquad());
32383249
if (PromotedOp1V == PromotedOp2V) {
@@ -4683,6 +4694,9 @@ bool llvm::isMathLibCallNoop(const CallBase *Call,
46834694
case LibFunc_nexttoward:
46844695
case LibFunc_nexttowardf:
46854696
case LibFunc_nexttowardl: {
4697+
// The two arguments of nexttoward can have differing semantics.
4698+
// We need to convert both arguments to the same semantics so
4699+
// we can do comparisons.
46864700
APFloat PromotedOp0 = Op0.getPromoted(APFloat::IEEEquad());
46874701
APFloat PromotedOp1 = Op1.getPromoted(APFloat::IEEEquad());
46884702
if (PromotedOp0 == PromotedOp1)

llvm/test/Transforms/InstCombine/constant-fold-nextafter.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ define double @nextafter_can_constant_fold_with_nan_arg() {
3939
%next = call double @nextafter(double 1.0, double %arg)
4040
ret double %next
4141
}
42+
define double @nextafter_constant_fold_propagates_nan_payload() {
43+
; CHECK-LABEL: define double @nextafter_constant_fold_propagates_nan_payload() {
44+
; CHECK-NEXT: ret double 0x7FF8000000000001
45+
;
46+
%nan = load double, double* @dbl_nan
47+
%tmp1 = bitcast double %nan to i64
48+
%tmp2 = or i64 %tmp1, 1
49+
%nan_with_payload = bitcast i64 %tmp2 to double
50+
%next = call double @nextafter(double %nan_with_payload, double 1.0)
51+
ret double %next
52+
}
4253
define double @nextafter_not_marked_dead_on_pos_overflow () {
4354
; CHECK-LABEL: define double @nextafter_not_marked_dead_on_pos_overflow() {
4455
; CHECK-NEXT: [[NEXT:%.*]] = call double @nextafter(double 0x7FEFFFFFFFFFFFFF, double 0x7FF0000000000000)
@@ -121,6 +132,17 @@ define float @nextafterf_can_constant_fold_with_nan_arg() {
121132
%next = call float @nextafterf(float 1.0, float %arg)
122133
ret float %next
123134
}
135+
define float @nextafterf_constant_fold_propagates_nan_payload() {
136+
; CHECK-LABEL: define float @nextafterf_constant_fold_propagates_nan_payload() {
137+
; CHECK-NEXT: ret float 0x7FF8000020000000
138+
;
139+
%nan = load float, float* @flt_nan
140+
%tmp1 = bitcast float %nan to i32
141+
%tmp2 = or i32 %tmp1, 1
142+
%nan_with_payload = bitcast i32 %tmp2 to float
143+
%next = call float @nextafterf(float %nan_with_payload, float 1.0)
144+
ret float %next
145+
}
124146
define float @nextafterf_not_marked_dead_on_pos_overflow() {
125147
; CHECK-LABEL: define float @nextafterf_not_marked_dead_on_pos_overflow() {
126148
; CHECK-NEXT: [[NEXT:%.*]] = call float @nextafterf(float 0x47EFFFFFE0000000, float 0x7FF0000000000000)

llvm/test/Transforms/InstCombine/constant-fold-nexttoward-fp128.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ define double @nexttoward_can_constant_fold_with_nan_arg() {
4343
%next = call double @nexttoward(double 1.0, fp128 %arg)
4444
ret double %next
4545
}
46+
define double @nexttoward_constant_fold_propagates_nan_payload() {
47+
; CHECK-LABEL: define double @nexttoward_constant_fold_propagates_nan_payload() {
48+
; CHECK-NEXT: ret double 0x7FF8000000000001
49+
;
50+
%nan = load double, double* @dbl_nan
51+
%tmp1 = bitcast double %nan to i64
52+
%tmp2 = or i64 %tmp1, 1
53+
%nan_with_payload = bitcast i64 %tmp2 to double
54+
%dummy_arg = fpext double 1.0 to fp128
55+
%next = call double @nexttoward(double %nan_with_payload, fp128 %dummy_arg)
56+
ret double %next
57+
}
4658
define double @nexttoward_not_marked_dead_on_pos_overflow() {
4759
; CHECK-LABEL: define double @nexttoward_not_marked_dead_on_pos_overflow() {
4860
; CHECK-NEXT: [[NEXT:%.*]] = call double @nexttoward(double 0x7FEFFFFFFFFFFFFF, fp128 0xL00000000000000007FFF000000000000)
@@ -133,6 +145,18 @@ define float @nexttowardf_can_constant_fold_with_nan_arg() {
133145
%next = call float @nexttowardf(float 1.0, fp128 %ext_nan)
134146
ret float %next
135147
}
148+
define float @nexttowardf_constant_fold_propagates_nan_payload() {
149+
; CHECK-LABEL: define float @nexttowardf_constant_fold_propagates_nan_payload() {
150+
; CHECK-NEXT: ret float 0x7FF8000020000000
151+
;
152+
%nan = load float, float* @flt_nan
153+
%tmp1 = bitcast float %nan to i32
154+
%tmp2 = or i32 %tmp1, 1
155+
%nan_with_payload = bitcast i32 %tmp2 to float
156+
%dummy_arg = fpext float 1.0 to fp128
157+
%next = call float @nexttowardf(float %nan_with_payload, fp128 %dummy_arg)
158+
ret float %next
159+
}
136160
define float @nexttowardf_not_marked_dead_on_pos_overflow () {
137161
; CHECK-LABEL: define float @nexttowardf_not_marked_dead_on_pos_overflow() {
138162
; CHECK-NEXT: [[NEXT:%.*]] = call float @nexttowardf(float 0x47EFFFFFE0000000, fp128 0xL00000000000000007FFF000000000000)

llvm/test/Transforms/InstCombine/constant-fold-nexttoward-ppc-fp128.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ define double @nexttoward_can_constant_fold_with_nan_arg() {
4343
%next = call double @nexttoward(double 1.0, ppc_fp128 %arg)
4444
ret double %next
4545
}
46+
define double @nexttoward_constant_fold_propagates_nan_payload() {
47+
; CHECK-LABEL: define double @nexttoward_constant_fold_propagates_nan_payload() {
48+
; CHECK-NEXT: ret double 0x7FF8000000000001
49+
;
50+
%nan = load double, double* @dbl_nan
51+
%tmp1 = bitcast double %nan to i64
52+
%tmp2 = or i64 %tmp1, 1
53+
%nan_with_payload = bitcast i64 %tmp2 to double
54+
%dummy_arg = fpext double 1.0 to ppc_fp128
55+
%next = call double @nexttoward(double %nan_with_payload, ppc_fp128 %dummy_arg)
56+
ret double %next
57+
}
4658
define double @nexttoward_not_marked_dead_on_pos_overflow() {
4759
; CHECK-LABEL: define double @nexttoward_not_marked_dead_on_pos_overflow() {
4860
; CHECK-NEXT: [[NEXT:%.*]] = call double @nexttoward(double 0x7FEFFFFFFFFFFFFF, ppc_fp128 0xM7FF00000000000000000000000000000)
@@ -133,6 +145,18 @@ define float @nexttowardf_can_constant_fold_with_nan_arg() {
133145
%next = call float @nexttowardf(float 1.0, ppc_fp128 %ext_nan)
134146
ret float %next
135147
}
148+
define float @nexttowardf_constant_fold_propagates_nan_payload() {
149+
; CHECK-LABEL: define float @nexttowardf_constant_fold_propagates_nan_payload() {
150+
; CHECK-NEXT: ret float 0x7FF8000020000000
151+
;
152+
%nan = load float, float* @flt_nan
153+
%tmp1 = bitcast float %nan to i32
154+
%tmp2 = or i32 %tmp1, 1
155+
%nan_with_payload = bitcast i32 %tmp2 to float
156+
%dummy_arg = fpext float 1.0 to ppc_fp128
157+
%next = call float @nexttowardf(float %nan_with_payload, ppc_fp128 %dummy_arg)
158+
ret float %next
159+
}
136160
define float @nexttowardf_not_marked_dead_on_pos_overflow () {
137161
; CHECK-LABEL: define float @nexttowardf_not_marked_dead_on_pos_overflow() {
138162
; CHECK-NEXT: [[NEXT:%.*]] = call float @nexttowardf(float 0x47EFFFFFE0000000, ppc_fp128 0xM7FF00000000000000000000000000000)

llvm/test/Transforms/InstCombine/constant-fold-nexttoward-x86-fp80.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ define double @nexttoward_can_constant_fold_with_nan_arg() {
4343
%next = call double @nexttoward(double 1.0, x86_fp80 %arg)
4444
ret double %next
4545
}
46+
define double @nexttoward_constant_fold_propagates_nan_payload() {
47+
; CHECK-LABEL: define double @nexttoward_constant_fold_propagates_nan_payload() {
48+
; CHECK-NEXT: ret double 0x7FF8000000000001
49+
;
50+
%nan = load double, double* @dbl_nan
51+
%tmp1 = bitcast double %nan to i64
52+
%tmp2 = or i64 %tmp1, 1
53+
%nan_with_payload = bitcast i64 %tmp2 to double
54+
%dummy_arg = fpext double 1.0 to x86_fp80
55+
%next = call double @nexttoward(double %nan_with_payload, x86_fp80 %dummy_arg)
56+
ret double %next
57+
}
4658
define double @nexttoward_not_marked_dead_on_pos_overflow () {
4759
; CHECK-LABEL: define double @nexttoward_not_marked_dead_on_pos_overflow() {
4860
; CHECK-NEXT: [[NEXT:%.*]] = call double @nexttoward(double 0x7FEFFFFFFFFFFFFF, x86_fp80 0xK7FFF8000000000000000)
@@ -133,6 +145,18 @@ define float @nexttowardf_can_constant_fold_with_nan_arg() {
133145
%next = call float @nexttowardf(float 1.0, x86_fp80 %ext_nan)
134146
ret float %next
135147
}
148+
define float @nexttowardf_constant_fold_propagates_nan_payload() {
149+
; CHECK-LABEL: define float @nexttowardf_constant_fold_propagates_nan_payload() {
150+
; CHECK-NEXT: ret float 0x7FF8000020000000
151+
;
152+
%nan = load float, float* @flt_nan
153+
%tmp1 = bitcast float %nan to i32
154+
%tmp2 = or i32 %tmp1, 1
155+
%nan_with_payload = bitcast i32 %tmp2 to float
156+
%dummy_arg = fpext float 1.0 to x86_fp80
157+
%next = call float @nexttowardf(float %nan_with_payload, x86_fp80 %dummy_arg)
158+
ret float %next
159+
}
136160
define float @nexttowardf_not_marked_dead_on_pos_overflow() {
137161
; CHECK-LABEL: define float @nexttowardf_not_marked_dead_on_pos_overflow() {
138162
; CHECK-NEXT: [[NEXT:%.*]] = call float @nexttowardf(float 0x47EFFFFFE0000000, x86_fp80 0xK7FFF8000000000000000)

0 commit comments

Comments
 (0)