Skip to content

Commit f60d26d

Browse files
[IndVarSimplify] Ensure fp values can be represented as consecutive integers
When transforming floating-point induction variables into integer ones, make sure we stay within the bounds of fp values that can be represented as integers without gaps, i.e., 2^24 and 2^53 for IEEE-754 single and double precision respectively (both on negative and positive side). Fixes: #166496.
1 parent 7038288 commit f60d26d

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,24 @@ static bool ConvertToSInt(const APFloat &APF, int64_t &IntVal) {
196196
return true;
197197
}
198198

199+
// Ensure we stay within the bounds of fp values that can be represented as
200+
// integers without gaps, namely 2^24 and 2^53 for IEEE-754 single and double
201+
// precision respectively (both on negative and positive side).
202+
static bool isRepresentableAsExactInteger(ConstantFP *FPVal, int64_t IntVal) {
203+
const auto &InitValueFltSema = FPVal->getValueAPF().getSemantics();
204+
if (!APFloat::isIEEELikeFP(InitValueFltSema))
205+
return false;
206+
207+
uint64_t InitValuePrecision = APFloat::semanticsPrecision(InitValueFltSema);
208+
if (InitValuePrecision >= 64)
209+
return false;
210+
211+
uint64_t InitValueIntegerLimit = 1LL << InitValuePrecision;
212+
if (AbsoluteValue(IntVal) >= InitValueIntegerLimit)
213+
return false;
214+
return true;
215+
}
216+
199217
/// If the loop has floating induction variable then insert corresponding
200218
/// integer induction variable if possible.
201219
/// For example,
@@ -212,7 +230,8 @@ bool IndVarSimplify::handleFloatingPointIV(Loop *L, PHINode *PN) {
212230
auto *InitValueVal = dyn_cast<ConstantFP>(PN->getIncomingValue(IncomingEdge));
213231

214232
int64_t InitValue;
215-
if (!InitValueVal || !ConvertToSInt(InitValueVal->getValueAPF(), InitValue))
233+
if (!InitValueVal || !ConvertToSInt(InitValueVal->getValueAPF(), InitValue) ||
234+
!isRepresentableAsExactInteger(InitValueVal, InitValue))
216235
return false;
217236

218237
// Check IV increment. Reject this PN if increment operation is not
@@ -262,7 +281,8 @@ bool IndVarSimplify::handleFloatingPointIV(Loop *L, PHINode *PN) {
262281
ConstantFP *ExitValueVal = dyn_cast<ConstantFP>(Compare->getOperand(1));
263282
int64_t ExitValue;
264283
if (ExitValueVal == nullptr ||
265-
!ConvertToSInt(ExitValueVal->getValueAPF(), ExitValue))
284+
!ConvertToSInt(ExitValueVal->getValueAPF(), ExitValue) ||
285+
!isRepresentableAsExactInteger(ExitValueVal, ExitValue))
266286
return false;
267287

268288
// Find new predicate for integer comparison.

llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -418,16 +418,15 @@ exit:
418418
ret void
419419
}
420420

421-
; FIXME: These are miscompilation issues.
422421
define void @test_fp_to_int_irrealizable_initval() {
423422
; CHECK-LABEL: @test_fp_to_int_irrealizable_initval(
424423
; CHECK-NEXT: entry:
425424
; CHECK-NEXT: br label [[LOOP:%.*]]
426425
; CHECK: loop:
427-
; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 100000000, [[ENTRY:%.*]] ], [ [[IV_NEXT_INT:%.*]], [[LOOP]] ]
426+
; CHECK-NEXT: [[IV:%.*]] = phi float [ 1.000000e+08, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
428427
; CHECK-NEXT: call void @opaque()
429-
; CHECK-NEXT: [[IV_NEXT_INT]] = add nsw i32 [[IV_INT]], -17
430-
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[IV_NEXT_INT]], 25
428+
; CHECK-NEXT: [[IV_NEXT]] = fadd float [[IV]], -1.700000e+01
429+
; CHECK-NEXT: [[CMP:%.*]] = fcmp ult float [[IV_NEXT]], 2.500000e+01
431430
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
432431
; CHECK: exit:
433432
; CHECK-NEXT: ret void
@@ -451,10 +450,10 @@ define void @test_fp_to_int_irrealizable_exitval() {
451450
; CHECK-NEXT: entry:
452451
; CHECK-NEXT: br label [[LOOP:%.*]]
453452
; CHECK: loop:
454-
; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 25, [[ENTRY:%.*]] ], [ [[IV_NEXT_INT:%.*]], [[LOOP]] ]
453+
; CHECK-NEXT: [[IV:%.*]] = phi float [ 2.500000e+01, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
455454
; CHECK-NEXT: call void @opaque()
456-
; CHECK-NEXT: [[IV_NEXT_INT]] = add nuw nsw i32 [[IV_INT]], 17
457-
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[IV_NEXT_INT]], 100000000
455+
; CHECK-NEXT: [[IV_NEXT]] = fadd float [[IV]], 1.700000e+01
456+
; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[IV_NEXT]], 1.000000e+08
458457
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
459458
; CHECK: exit:
460459
; CHECK-NEXT: ret void
@@ -478,10 +477,10 @@ define void @test_fp_to_int_irrealizable_negative_exitval() {
478477
; CHECK-NEXT: entry:
479478
; CHECK-NEXT: br label [[LOOP:%.*]]
480479
; CHECK: loop:
481-
; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ -25, [[ENTRY:%.*]] ], [ [[IV_NEXT_INT:%.*]], [[LOOP]] ]
480+
; CHECK-NEXT: [[IV:%.*]] = phi float [ -2.500000e+01, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
482481
; CHECK-NEXT: call void @opaque()
483-
; CHECK-NEXT: [[IV_NEXT_INT]] = add nsw i32 [[IV_INT]], -17
484-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_NEXT_INT]], -100000000
482+
; CHECK-NEXT: [[IV_NEXT]] = fadd float [[IV]], -1.700000e+01
483+
; CHECK-NEXT: [[CMP:%.*]] = fcmp ult float [[IV_NEXT]], -1.000000e+08
485484
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
486485
; CHECK: exit:
487486
; CHECK-NEXT: ret void
@@ -505,10 +504,10 @@ define void @test_fp_to_int_irrealizable_exitval_pow_2_24() {
505504
; CHECK-NEXT: entry:
506505
; CHECK-NEXT: br label [[LOOP:%.*]]
507506
; CHECK: loop:
508-
; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_INT:%.*]], [[LOOP]] ]
507+
; CHECK-NEXT: [[IV:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
509508
; CHECK-NEXT: call void @opaque()
510-
; CHECK-NEXT: [[IV_NEXT_INT]] = add nuw nsw i32 [[IV_INT]], 1
511-
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[IV_NEXT_INT]], 16777216
509+
; CHECK-NEXT: [[IV_NEXT]] = fadd float [[IV]], 1.000000e+00
510+
; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[IV_NEXT]], 0x4170000000000000
512511
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
513512
; CHECK: exit:
514513
; CHECK-NEXT: ret void

0 commit comments

Comments
 (0)