@@ -59,107 +59,130 @@ static void ForeachNumInConstantRange(const ConstantRange &CR, Fn TestFn) {
59
59
}
60
60
}
61
61
62
- template <typename Fn1, typename Fn2>
63
- static void TestUnsignedUnaryOpExhaustive (
64
- Fn1 RangeFn, Fn2 IntFn, bool SkipSignedIntMin = false ) {
62
+ struct OpRangeGathererBase {
63
+ void account (const APInt &N);
64
+ ConstantRange getRange ();
65
+ };
66
+
67
+ struct UnsignedOpRangeGatherer : public OpRangeGathererBase {
68
+ APInt Min;
69
+ APInt Max;
70
+
71
+ UnsignedOpRangeGatherer (unsigned Bits)
72
+ : Min(APInt::getMaxValue(Bits)), Max(APInt::getMinValue(Bits)) {}
73
+
74
+ void account (const APInt &N) {
75
+ if (N.ult (Min))
76
+ Min = N;
77
+ if (N.ugt (Max))
78
+ Max = N;
79
+ }
80
+
81
+ ConstantRange getRange () {
82
+ if (Min.ugt (Max))
83
+ return ConstantRange::getEmpty (Min.getBitWidth ());
84
+ return ConstantRange::getNonEmpty (Min, Max + 1 );
85
+ }
86
+ };
87
+
88
+ struct SignedOpRangeGatherer : public OpRangeGathererBase {
89
+ APInt Min;
90
+ APInt Max;
91
+
92
+ SignedOpRangeGatherer (unsigned Bits)
93
+ : Min(APInt::getSignedMaxValue(Bits)),
94
+ Max (APInt::getSignedMinValue(Bits)) {}
95
+
96
+ void account (const APInt &N) {
97
+ if (N.slt (Min))
98
+ Min = N;
99
+ if (N.sgt (Max))
100
+ Max = N;
101
+ }
102
+
103
+ ConstantRange getRange () {
104
+ if (Min.sgt (Max))
105
+ return ConstantRange::getEmpty (Min.getBitWidth ());
106
+ return ConstantRange::getNonEmpty (Min, Max + 1 );
107
+ }
108
+ };
109
+
110
+ template <typename Fn1, typename Fn2>
111
+ static void TestUnsignedUnaryOpExhaustive (Fn1 RangeFn, Fn2 IntFn,
112
+ bool SkipSignedIntMin = false ) {
65
113
unsigned Bits = 4 ;
66
114
EnumerateConstantRanges (Bits, [&](const ConstantRange &CR) {
67
- APInt Min = APInt::getMaxValue (Bits);
68
- APInt Max = APInt::getMinValue (Bits);
115
+ UnsignedOpRangeGatherer R (CR.getBitWidth ());
69
116
ForeachNumInConstantRange (CR, [&](const APInt &N) {
70
117
if (SkipSignedIntMin && N.isMinSignedValue ())
71
118
return ;
72
-
73
- APInt AbsN = IntFn (N);
74
- if (AbsN.ult (Min))
75
- Min = AbsN;
76
- if (AbsN.ugt (Max))
77
- Max = AbsN;
119
+ R.account (IntFn (N));
78
120
});
79
121
80
- ConstantRange ResultCR = RangeFn (CR);
81
- if (Min.ugt (Max)) {
82
- EXPECT_TRUE (ResultCR.isEmptySet ());
83
- return ;
84
- }
122
+ ConstantRange ExactCR = R.getRange ();
123
+ ConstantRange ActualCR = RangeFn (CR);
85
124
86
- ConstantRange Exact = ConstantRange::getNonEmpty (Min, Max + 1 );
87
- EXPECT_EQ (Exact, ResultCR);
125
+ EXPECT_EQ (ExactCR, ActualCR);
88
126
});
89
127
}
90
128
91
- template <typename Fn1, typename Fn2>
92
- static void TestUnsignedBinOpExhaustive (
93
- Fn1 RangeFn, Fn2 IntFn ,
94
- bool SkipZeroRHS = false , bool CorrectnessOnly = false ) {
129
+ template <typename Fn1, typename Fn2>
130
+ static void TestUnsignedBinOpExhaustive (Fn1 RangeFn, Fn2 IntFn,
131
+ bool SkipZeroRHS = false ,
132
+ bool CorrectnessOnly = false ) {
95
133
unsigned Bits = 4 ;
96
- EnumerateTwoConstantRanges (Bits, [&](const ConstantRange &CR1,
97
- const ConstantRange &CR2) {
98
- APInt Min = APInt::getMaxValue (Bits);
99
- APInt Max = APInt::getMinValue (Bits);
100
- ForeachNumInConstantRange (CR1, [&](const APInt &N1) {
101
- ForeachNumInConstantRange (CR2, [&](const APInt &N2) {
102
- if (SkipZeroRHS && N2 == 0 )
103
- return ;
134
+ EnumerateTwoConstantRanges (
135
+ Bits, [&](const ConstantRange &CR1, const ConstantRange &CR2) {
136
+ UnsignedOpRangeGatherer R (CR1.getBitWidth ());
137
+ ForeachNumInConstantRange (CR1, [&](const APInt &N1) {
138
+ ForeachNumInConstantRange (CR2, [&](const APInt &N2) {
139
+ if (SkipZeroRHS && N2 == 0 )
140
+ return ;
141
+ R.account (IntFn (N1, N2));
142
+ });
143
+ });
104
144
105
- APInt N = IntFn (N1, N2);
106
- if (N.ult (Min))
107
- Min = N;
108
- if (N.ugt (Max))
109
- Max = N;
110
- });
111
- });
145
+ ConstantRange CR = RangeFn (CR1, CR2);
112
146
113
- ConstantRange CR = RangeFn (CR1, CR2);
114
- if (Min.ugt (Max)) {
115
- EXPECT_TRUE (CR.isEmptySet ());
116
- return ;
117
- }
147
+ ConstantRange Exact = R.getRange ();
118
148
119
- ConstantRange Exact = ConstantRange::getNonEmpty (Min, Max + 1 );
120
- if (CorrectnessOnly) {
121
- EXPECT_TRUE (CR.contains (Exact));
122
- } else {
123
- EXPECT_EQ (Exact, CR);
124
- }
125
- });
149
+ if (!CorrectnessOnly) {
150
+ EXPECT_EQ (Exact, CR);
151
+ return ;
152
+ }
153
+
154
+ EXPECT_TRUE (CR.contains (Exact));
155
+ if (Exact.isEmptySet ())
156
+ EXPECT_TRUE (CR.isEmptySet ());
157
+ });
126
158
}
127
159
128
- template <typename Fn1, typename Fn2>
129
- static void TestSignedBinOpExhaustive (
130
- Fn1 RangeFn, Fn2 IntFn ,
131
- bool SkipZeroRHS = false , bool CorrectnessOnly = false ) {
160
+ template <typename Fn1, typename Fn2>
161
+ static void TestSignedBinOpExhaustive (Fn1 RangeFn, Fn2 IntFn,
162
+ bool SkipZeroRHS = false ,
163
+ bool CorrectnessOnly = false ) {
132
164
unsigned Bits = 4 ;
133
- EnumerateTwoConstantRanges (Bits, [&](const ConstantRange &CR1,
134
- const ConstantRange &CR2) {
135
- APInt Min = APInt::getSignedMaxValue (Bits);
136
- APInt Max = APInt::getSignedMinValue (Bits);
137
- ForeachNumInConstantRange (CR1, [&](const APInt &N1) {
138
- ForeachNumInConstantRange (CR2, [&](const APInt &N2) {
139
- if (SkipZeroRHS && N2 == 0 )
140
- return ;
165
+ EnumerateTwoConstantRanges (
166
+ Bits, [&](const ConstantRange &CR1, const ConstantRange &CR2) {
167
+ SignedOpRangeGatherer R (CR1.getBitWidth ());
168
+ ForeachNumInConstantRange (CR1, [&](const APInt &N1) {
169
+ ForeachNumInConstantRange (CR2, [&](const APInt &N2) {
170
+ if (SkipZeroRHS && N2 == 0 )
171
+ return ;
141
172
142
- APInt N = IntFn (N1, N2);
143
- if (N.slt (Min))
144
- Min = N;
145
- if (N.sgt (Max))
146
- Max = N;
147
- });
148
- });
173
+ R.account (IntFn (N1, N2));
174
+ });
175
+ });
149
176
150
- ConstantRange CR = RangeFn (CR1, CR2);
151
- if (Min.sgt (Max)) {
152
- EXPECT_TRUE (CR.isEmptySet ());
153
- return ;
154
- }
177
+ ConstantRange CR = RangeFn (CR1, CR2);
155
178
156
- ConstantRange Exact = ConstantRange::getNonEmpty (Min, Max + 1 );
157
- if (CorrectnessOnly) {
158
- EXPECT_TRUE (CR.contains (Exact));
159
- } else {
160
- EXPECT_EQ (Exact, CR);
161
- }
162
- });
179
+ ConstantRange Exact = R. getRange ( );
180
+ if (CorrectnessOnly) {
181
+ EXPECT_TRUE (CR.contains (Exact));
182
+ } else {
183
+ EXPECT_EQ (Exact, CR);
184
+ }
185
+ });
163
186
}
164
187
165
188
ConstantRange ConstantRangeTest::Full (16 , true );
@@ -731,35 +754,27 @@ static void TestAddWithNoSignedWrapExhaustive(Fn1 RangeFn, Fn2 IntFn) {
731
754
EnumerateTwoConstantRanges (Bits, [&](const ConstantRange &CR1,
732
755
const ConstantRange &CR2) {
733
756
ConstantRange CR = RangeFn (CR1, CR2);
734
- APInt Min = APInt::getSignedMaxValue (Bits);
735
- APInt Max = APInt::getSignedMinValue (Bits);
757
+ SignedOpRangeGatherer R (CR.getBitWidth ());
736
758
bool AllOverflow = true ;
737
759
ForeachNumInConstantRange (CR1, [&](const APInt &N1) {
738
760
ForeachNumInConstantRange (CR2, [&](const APInt &N2) {
739
761
bool IsOverflow = false ;
740
762
APInt N = IntFn (IsOverflow, N1, N2);
741
763
if (!IsOverflow) {
742
764
AllOverflow = false ;
743
- if (N.slt (Min))
744
- Min = N;
745
- if (N.sgt (Max))
746
- Max = N;
765
+ R.account (N);
747
766
EXPECT_TRUE (CR.contains (N));
748
767
}
749
768
});
750
769
});
751
770
752
771
EXPECT_EQ (CR.isEmptySet (), AllOverflow);
753
772
754
- if (!CR1.isSignWrappedSet () && !CR2.isSignWrappedSet ()) {
755
- if (Min.sgt (Max)) {
756
- EXPECT_TRUE (CR.isEmptySet ());
757
- return ;
758
- }
773
+ if (CR1.isSignWrappedSet () || CR2.isSignWrappedSet ())
774
+ return ;
759
775
760
- ConstantRange Exact = ConstantRange::getNonEmpty (Min, Max + 1 );
761
- EXPECT_EQ (Exact, CR);
762
- }
776
+ ConstantRange Exact = R.getRange ();
777
+ EXPECT_EQ (Exact, CR);
763
778
});
764
779
}
765
780
@@ -769,35 +784,27 @@ static void TestAddWithNoUnsignedWrapExhaustive(Fn1 RangeFn, Fn2 IntFn) {
769
784
EnumerateTwoConstantRanges (Bits, [&](const ConstantRange &CR1,
770
785
const ConstantRange &CR2) {
771
786
ConstantRange CR = RangeFn (CR1, CR2);
772
- APInt Min = APInt::getMaxValue (Bits);
773
- APInt Max = APInt::getMinValue (Bits);
787
+ UnsignedOpRangeGatherer R (CR.getBitWidth ());
774
788
bool AllOverflow = true ;
775
789
ForeachNumInConstantRange (CR1, [&](const APInt &N1) {
776
790
ForeachNumInConstantRange (CR2, [&](const APInt &N2) {
777
791
bool IsOverflow = false ;
778
792
APInt N = IntFn (IsOverflow, N1, N2);
779
793
if (!IsOverflow) {
780
794
AllOverflow = false ;
781
- if (N.ult (Min))
782
- Min = N;
783
- if (N.ugt (Max))
784
- Max = N;
795
+ R.account (N);
785
796
EXPECT_TRUE (CR.contains (N));
786
797
}
787
798
});
788
799
});
789
800
790
801
EXPECT_EQ (CR.isEmptySet (), AllOverflow);
791
802
792
- if (!CR1.isWrappedSet () && !CR2.isWrappedSet ()) {
793
- if (Min.ugt (Max)) {
794
- EXPECT_TRUE (CR.isEmptySet ());
795
- return ;
796
- }
803
+ if (CR1.isWrappedSet () || CR2.isWrappedSet ())
804
+ return ;
797
805
798
- ConstantRange Exact = ConstantRange::getNonEmpty (Min, Max + 1 );
799
- EXPECT_EQ (Exact, CR);
800
- }
806
+ ConstantRange Exact = R.getRange ();
807
+ EXPECT_EQ (Exact, CR);
801
808
});
802
809
}
803
810
@@ -809,10 +816,8 @@ static void TestAddWithNoSignedUnsignedWrapExhaustive(Fn1 RangeFn,
809
816
EnumerateTwoConstantRanges (
810
817
Bits, [&](const ConstantRange &CR1, const ConstantRange &CR2) {
811
818
ConstantRange CR = RangeFn (CR1, CR2);
812
- APInt UMin = APInt::getMaxValue (Bits);
813
- APInt UMax = APInt::getMinValue (Bits);
814
- APInt SMin = APInt::getSignedMaxValue (Bits);
815
- APInt SMax = APInt::getSignedMinValue (Bits);
819
+ UnsignedOpRangeGatherer UR (CR.getBitWidth ());
820
+ SignedOpRangeGatherer SR (CR.getBitWidth ());
816
821
bool AllOverflow = true ;
817
822
ForeachNumInConstantRange (CR1, [&](const APInt &N1) {
818
823
ForeachNumInConstantRange (CR2, [&](const APInt &N2) {
@@ -821,33 +826,29 @@ static void TestAddWithNoSignedUnsignedWrapExhaustive(Fn1 RangeFn,
821
826
(void ) IntFnUnsigned (IsOverflow, N1, N2);
822
827
if (!IsSignedOverflow && !IsOverflow) {
823
828
AllOverflow = false ;
824
- if (N.slt (SMin))
825
- SMin = N;
826
- if (N.sgt (SMax))
827
- SMax = N;
828
- if (N.ult (UMin))
829
- UMin = N;
830
- if (N.ugt (UMax))
831
- UMax = N;
829
+ UR.account (N);
830
+ SR.account (N);
832
831
EXPECT_TRUE (CR.contains (N));
833
832
}
834
833
});
835
834
});
836
835
837
836
EXPECT_EQ (CR.isEmptySet (), AllOverflow);
838
837
839
- if (!CR1.isWrappedSet () && !CR2.isWrappedSet () &&
840
- !CR1.isSignWrappedSet () && !CR2.isSignWrappedSet ()) {
841
- if (UMin.ugt (UMax) || SMin.sgt (SMax)) {
842
- EXPECT_TRUE (CR.isEmptySet ());
843
- return ;
844
- }
838
+ if (CR1.isWrappedSet () || CR2.isWrappedSet () ||
839
+ CR1.isSignWrappedSet () || CR2.isSignWrappedSet ())
840
+ return ;
845
841
846
- ConstantRange Exact =
847
- ConstantRange::getNonEmpty (SMin, SMax + 1 )
848
- .intersectWith (ConstantRange::getNonEmpty (UMin, UMax + 1 ));
849
- EXPECT_EQ (Exact, CR);
842
+ ConstantRange ExactUnsignedCR = UR.getRange ();
843
+ ConstantRange ExactSignedCR = SR.getRange ();
844
+
845
+ if (ExactUnsignedCR.isEmptySet () || ExactSignedCR.isEmptySet ()) {
846
+ EXPECT_TRUE (CR.isEmptySet ());
847
+ return ;
850
848
}
849
+
850
+ ConstantRange Exact = ExactSignedCR.intersectWith (ExactUnsignedCR);
851
+ EXPECT_EQ (Exact, CR);
851
852
});
852
853
}
853
854
@@ -2229,23 +2230,19 @@ TEST_F(ConstantRangeTest, FromKnownBitsExhaustive) {
2229
2230
if (Known.hasConflict () || Known.isUnknown ())
2230
2231
continue ;
2231
2232
2232
- APInt MinUnsigned = APInt::getMaxValue (Bits);
2233
- APInt MaxUnsigned = APInt::getMinValue (Bits);
2234
- APInt MinSigned = APInt::getSignedMaxValue (Bits);
2235
- APInt MaxSigned = APInt::getSignedMinValue (Bits);
2233
+ UnsignedOpRangeGatherer UR (Bits);
2234
+ SignedOpRangeGatherer SR (Bits);
2236
2235
for (unsigned N = 0 ; N < Max; ++N) {
2237
2236
APInt Num (Bits, N);
2238
2237
if ((Num & Known.Zero ) != 0 || (~Num & Known.One ) != 0 )
2239
2238
continue ;
2240
2239
2241
- if (Num.ult (MinUnsigned)) MinUnsigned = Num;
2242
- if (Num.ugt (MaxUnsigned)) MaxUnsigned = Num;
2243
- if (Num.slt (MinSigned)) MinSigned = Num;
2244
- if (Num.sgt (MaxSigned)) MaxSigned = Num;
2240
+ UR.account (Num);
2241
+ SR.account (Num);
2245
2242
}
2246
2243
2247
- ConstantRange UnsignedCR (MinUnsigned, MaxUnsigned + 1 );
2248
- ConstantRange SignedCR (MinSigned, MaxSigned + 1 );
2244
+ ConstantRange UnsignedCR = UR. getRange ( );
2245
+ ConstantRange SignedCR = SR. getRange ( );
2249
2246
EXPECT_EQ (UnsignedCR, ConstantRange::fromKnownBits (Known, false ));
2250
2247
EXPECT_EQ (SignedCR, ConstantRange::fromKnownBits (Known, true ));
2251
2248
}
0 commit comments