Skip to content

Commit 099349d

Browse files
committed
[ValueTracking] Infer knownbits from fp classes
1 parent 3516f12 commit 099349d

File tree

3 files changed

+46
-39
lines changed

3 files changed

+46
-39
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ struct KnownFPClass {
263263
return (KnownFPClasses & Mask) == fcNone;
264264
}
265265

266+
/// Return true if it's known this can only be one of the mask entries.
267+
bool isKnownOnly(FPClassTest Mask) const {
268+
return (KnownFPClasses & ~Mask) == fcNone;
269+
}
270+
266271
bool isUnknown() const {
267272
return KnownFPClasses == fcAllFlags && !SignBit;
268273
}

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,37 @@ static void computeKnownBitsFromOperator(const Operator *I,
11051105
break;
11061106
}
11071107

1108+
Value *V;
1109+
// Handle bitcast from floating point to integer.
1110+
if (match(const_cast<Operator *>(I), m_ElementWiseBitCast(m_Value(V))) &&
1111+
V->getType()->isFPOrFPVectorTy()) {
1112+
KnownFPClass Result = computeKnownFPClass(V, fcAllFlags, Depth + 1, Q);
1113+
if (Result.SignBit) {
1114+
if (*Result.SignBit)
1115+
Known.makeNegative();
1116+
else
1117+
Known.makeNonNegative();
1118+
}
1119+
1120+
Type *FPType = V->getType()->getScalarType();
1121+
int MantissaWidth = FPType->getFPMantissaWidth();
1122+
if (MantissaWidth != -1) {
1123+
if (Result.isKnownOnly(fcInf)) {
1124+
Known.Zero.setLowBits(MantissaWidth);
1125+
Known.One.setBits(MantissaWidth, BitWidth - 1);
1126+
} else if (Result.isKnownOnly(fcZero))
1127+
Known.Zero.setLowBits(BitWidth - 1);
1128+
else if (Result.isKnownOnly(fcInf | fcNan))
1129+
Known.One.setBits(MantissaWidth, BitWidth - 1);
1130+
else if (Result.isKnownOnly(fcSubnormal | fcZero))
1131+
Known.Zero.setBits(MantissaWidth, BitWidth - 1);
1132+
else if (Result.isKnownOnly(fcInf | fcZero))
1133+
Known.Zero.setLowBits(MantissaWidth);
1134+
}
1135+
1136+
break;
1137+
}
1138+
11081139
// Handle cast from vector integer type to scalar or vector integer.
11091140
auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcTy);
11101141
if (!SrcVecTy || !SrcVecTy->getElementType()->isIntegerTy() ||

llvm/test/Transforms/InstCombine/known-bits.ll

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -485,10 +485,7 @@ if.else:
485485

486486
define i1 @test_sign_pos(float %x) {
487487
; CHECK-LABEL: @test_sign_pos(
488-
; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
489-
; CHECK-NEXT: [[Y:%.*]] = bitcast float [[FABS]] to i32
490-
; CHECK-NEXT: [[SIGN:%.*]] = icmp sgt i32 [[Y]], -1
491-
; CHECK-NEXT: ret i1 [[SIGN]]
488+
; CHECK-NEXT: ret i1 true
492489
;
493490
%fabs = call float @llvm.fabs.f32(float %x)
494491
%y = bitcast float %fabs to i32
@@ -498,11 +495,7 @@ define i1 @test_sign_pos(float %x) {
498495

499496
define i1 @test_sign_neg(float %x) {
500497
; CHECK-LABEL: @test_sign_neg(
501-
; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
502-
; CHECK-NEXT: [[FNABS:%.*]] = fneg float [[FABS]]
503-
; CHECK-NEXT: [[Y:%.*]] = bitcast float [[FNABS]] to i32
504-
; CHECK-NEXT: [[SIGN:%.*]] = icmp slt i32 [[Y]], 0
505-
; CHECK-NEXT: ret i1 [[SIGN]]
498+
; CHECK-NEXT: ret i1 true
506499
;
507500
%fabs = call float @llvm.fabs.f32(float %x)
508501
%fnabs = fneg float %fabs
@@ -513,10 +506,7 @@ define i1 @test_sign_neg(float %x) {
513506

514507
define <2 x i1> @test_sign_pos_vec(<2 x float> %x) {
515508
; CHECK-LABEL: @test_sign_pos_vec(
516-
; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
517-
; CHECK-NEXT: [[Y:%.*]] = bitcast <2 x float> [[FABS]] to <2 x i32>
518-
; CHECK-NEXT: [[SIGN:%.*]] = icmp slt <2 x i32> [[Y]], zeroinitializer
519-
; CHECK-NEXT: ret <2 x i1> [[SIGN]]
509+
; CHECK-NEXT: ret <2 x i1> zeroinitializer
520510
;
521511
%fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %x)
522512
%y = bitcast <2 x float> %fabs to <2 x i32>
@@ -526,9 +516,7 @@ define <2 x i1> @test_sign_pos_vec(<2 x float> %x) {
526516

527517
define i32 @test_inf_only(float nofpclass(nan sub norm zero) %x) {
528518
; CHECK-LABEL: @test_inf_only(
529-
; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
530-
; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32
531-
; CHECK-NEXT: ret i32 [[AND]]
519+
; CHECK-NEXT: ret i32 2130706432
532520
;
533521
%y = bitcast float %x to i32
534522
%and = and i32 %y, 2147483647
@@ -537,9 +525,7 @@ define i32 @test_inf_only(float nofpclass(nan sub norm zero) %x) {
537525

538526
define i32 @test_zero_only(float nofpclass(nan sub norm inf) %x) {
539527
; CHECK-LABEL: @test_zero_only(
540-
; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
541-
; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32
542-
; CHECK-NEXT: ret i32 [[AND]]
528+
; CHECK-NEXT: ret i32 0
543529
;
544530
%y = bitcast float %x to i32
545531
%and = and i32 %y, 2147483647
@@ -548,9 +534,7 @@ define i32 @test_zero_only(float nofpclass(nan sub norm inf) %x) {
548534

549535
define i32 @test_inf_nan_only(float nofpclass(sub norm zero) %x) {
550536
; CHECK-LABEL: @test_inf_nan_only(
551-
; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
552-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
553-
; CHECK-NEXT: ret i32 [[AND]]
537+
; CHECK-NEXT: ret i32 2130706432
554538
;
555539
%y = bitcast float %x to i32
556540
%and = and i32 %y, 2130706432
@@ -559,9 +543,7 @@ define i32 @test_inf_nan_only(float nofpclass(sub norm zero) %x) {
559543

560544
define i32 @test_sub_zero_only(float nofpclass(nan norm inf) %x) {
561545
; CHECK-LABEL: @test_sub_zero_only(
562-
; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
563-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
564-
; CHECK-NEXT: ret i32 [[AND]]
546+
; CHECK-NEXT: ret i32 0
565547
;
566548
%y = bitcast float %x to i32
567549
%and = and i32 %y, 2130706432
@@ -570,9 +552,7 @@ define i32 @test_sub_zero_only(float nofpclass(nan norm inf) %x) {
570552

571553
define i32 @test_inf_zero_only(float nofpclass(nan norm sub) %x) {
572554
; CHECK-LABEL: @test_inf_zero_only(
573-
; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
574-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 16777215
575-
; CHECK-NEXT: ret i32 [[AND]]
555+
; CHECK-NEXT: ret i32 0
576556
;
577557
%y = bitcast float %x to i32
578558
%and = and i32 %y, 16777215
@@ -581,11 +561,7 @@ define i32 @test_inf_zero_only(float nofpclass(nan norm sub) %x) {
581561

582562
define i1 @test_simplify_icmp(i32 %x) {
583563
; CHECK-LABEL: @test_simplify_icmp(
584-
; CHECK-NEXT: [[CONV_I_I:%.*]] = uitofp i32 [[X:%.*]] to double
585-
; CHECK-NEXT: [[TMP1:%.*]] = bitcast double [[CONV_I_I]] to i64
586-
; CHECK-NEXT: [[SHR_I_MASK_I:%.*]] = and i64 [[TMP1]], -140737488355328
587-
; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i64 [[SHR_I_MASK_I]], -1970324836974592
588-
; CHECK-NEXT: ret i1 [[CMP_I]]
564+
; CHECK-NEXT: ret i1 false
589565
;
590566
%conv.i.i = uitofp i32 %x to double
591567
%3 = bitcast double %conv.i.i to i64
@@ -600,12 +576,7 @@ define i16 @test_simplify_mask(i32 %ui, float %x) {
600576
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[CONV]], [[X:%.*]]
601577
; CHECK-NEXT: br i1 [[CMP]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
602578
; CHECK: if.end:
603-
; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[CONV]] to i32
604-
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[CAST]], 16
605-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i16
606-
; CHECK-NEXT: [[AND:%.*]] = and i16 [[TRUNC]], -32768
607-
; CHECK-NEXT: [[OR:%.*]] = or disjoint i16 [[AND]], 31744
608-
; CHECK-NEXT: ret i16 [[OR]]
579+
; CHECK-NEXT: ret i16 31744
609580
; CHECK: if.else:
610581
; CHECK-NEXT: ret i16 0
611582
;

0 commit comments

Comments
 (0)