@@ -37,6 +37,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3737// ===----------------------------------------------------------------------===//
3838#define DEBUG_TYPE " GENX_ALIGNMENT_INFO"
3939
40+ #include " IGC/common/StringMacros.hpp"
41+
4042#include < algorithm>
4143#include " GenX.h"
4244#include " GenXAlignmentInfo.h"
@@ -63,6 +65,7 @@ Alignment AlignmentInfo::get(Value *V)
6365 if (auto C = dyn_cast<Constant>(V))
6466 return Alignment (C);
6567 auto Inst = dyn_cast<Instruction>(V);
68+
6669 if (!Inst) {
6770 // An Argument has unknown alignment.
6871 // (FIXME: We may need to do better than this, tracing the value of the
@@ -141,8 +144,10 @@ Alignment AlignmentInfo::get(Value *V)
141144 Alignment A (0 , 0 ); // assume unknown
142145 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(WorkInst)) {
143146 A = Alignment (); // assume uncomputed
144- Alignment A0 = getFromInstMap (BO->getOperand (0 ));
145- Alignment A1 = getFromInstMap (BO->getOperand (1 ));
147+ auto *Op0 = BO->getOperand (0 );
148+ auto *Op1 = BO->getOperand (1 );
149+ Alignment A0 = getFromInstMap (Op0);
150+ Alignment A1 = getFromInstMap (Op1);
146151 if (!A0.isUncomputed () && !A1.isUncomputed ()) {
147152 switch (BO->getOpcode ()) {
148153 case Instruction::Add:
@@ -164,9 +169,17 @@ Alignment AlignmentInfo::get(Value *V)
164169 } else
165170 A = Alignment::getUnknown ();
166171 break ;
167- default :
168- A = Alignment::getUnknown ();
169- break ;
172+ case Instruction::And:
173+ if (auto *CI0 = dyn_cast<ConstantInt>(Op0)) {
174+ A = A1.logicalAnd (CI0);
175+ } else if (auto *CI1 = dyn_cast<ConstantInt>(Op1)) {
176+ A = A0.logicalAnd (CI1);
177+ } else
178+ A = Alignment::getUnknown ();
179+ break ;
180+ default :
181+ A = Alignment::getUnknown ();
182+ break ;
170183 }
171184 }
172185 } else if (CastInst *CI = dyn_cast<CastInst>(WorkInst)) {
@@ -201,11 +214,11 @@ Alignment AlignmentInfo::get(Value *V)
201214 switch (GenXIntrinsic::getGenXIntrinsicID (WorkInst)) {
202215 case GenXIntrinsic::genx_rdregioni:
203216 case GenXIntrinsic::genx_rdregionf: {
204- // Handle the case of reading a scalar from element 0 of a vector, as
217+ // Handle the case of reading a scalar from element of a vector, as
205218 // a trunc from i32 to i16 is lowered to a bitcast to v2i16 then a
206219 // rdregion.
207220 Region R (WorkInst, BaleInfo ());
208- if (!R.Indirect && !R. Offset )
221+ if (!R.Indirect && (R. NumElements == 1 ) )
209222 A = getFromInstMap (WorkInst->getOperand (0 ));
210223 else
211224 A = Alignment (0 , 0 );
@@ -275,7 +288,30 @@ Alignment::Alignment(unsigned C)
275288{
276289 LogAlign = countTrailingZeros (C);
277290 ExtraBits = 0 ;
278- ConstBits = (C < 0x7fffffff )? C : 0x7fffffff ;
291+ ConstBits = (C < MaskForUnknown) ? C : MaskForUnknown;
292+ }
293+
294+ Alignment Alignment::getAlignmentForConstant (Constant *C) {
295+ IGC_ASSERT (!isa<VectorType>(C->getType ()));
296+ Alignment A;
297+ A.setUncomputed ();
298+ if (isa<UndefValue>(C)) {
299+ A.LogAlign = 31 ;
300+ A.ExtraBits = 0 ;
301+ A.ConstBits = MaskForUnknown;
302+ } else if (auto CI = dyn_cast<ConstantInt>(C)) {
303+ int64_t SVal = CI->getSExtValue ();
304+ // Get least significant bits to count LogAlign
305+ unsigned LSBBits = SVal & UnsignedAllOnes;
306+ A.LogAlign = countTrailingZeros (LSBBits);
307+
308+ A.ExtraBits = 0 ;
309+ A.ConstBits = MaskForUnknown;
310+ if (SVal < MaskForUnknown && SVal >= 0 &&
311+ SVal <= std::numeric_limits<unsigned >::max ())
312+ A.ConstBits = static_cast <unsigned >(SVal);
313+ }
314+ return A;
279315}
280316
281317/* **********************************************************************
@@ -284,19 +320,18 @@ Alignment::Alignment(unsigned C)
284320Alignment::Alignment (Constant *C)
285321{
286322 setUncomputed ();
287- if (isa<VectorType>(C->getType ()))
288- C = C->getAggregateElement (0U );
289- if (isa<UndefValue>(C)) {
290- LogAlign = 31 ;
291- ExtraBits = 0 ;
292- ConstBits = 0x7fffffff ;
293- } else if (auto CI = dyn_cast<ConstantInt>(C)) {
294- LogAlign = countTrailingZeros ((unsigned )(CI->getSExtValue ()));
295- ExtraBits = 0 ;
296- ConstBits = 0x7fffffff ;
297- if (CI->getSExtValue () < 0x7fffffff && CI->getSExtValue () >= 0 )
298- ConstBits = (unsigned )(CI->getSExtValue ());
323+ if (auto *VT = dyn_cast<VectorType>(C->getType ())) {
324+ // Take splat if exists
325+ if (auto *SplatVal = C->getSplatValue ())
326+ C = SplatVal;
327+ else {
328+ // Otherwise be conservative and pretend alignment
329+ // unknown for non-splat vectors
330+ *this = Alignment::getUnknown ();
331+ return ;
332+ }
299333 }
334+ *this = getAlignmentForConstant (C);
300335}
301336
302337/* **********************************************************************
@@ -365,6 +400,24 @@ Alignment Alignment::mul(Alignment Other) const
365400 return Alignment (MinLogAlign, ExtraBits2 & ((1 << MinLogAlign) - 1 ));
366401}
367402
403+ /* **********************************************************************
404+ * logicalAnd : logical and two alignments. Only constant int supported.
405+ */
406+ Alignment Alignment::logicalAnd (ConstantInt *CI) const {
407+ IGC_ASSERT (!isUncomputed () && CI);
408+ // If value doesn't fit into unsigned then be conservative and pretend
409+ // that alignement is unknown
410+ int64_t Val = CI->getSExtValue ();
411+ if (Val < std::numeric_limits<int >::min () ||
412+ Val > std::numeric_limits<int >::max ())
413+ return Alignment::getUnknown ();
414+ unsigned UVal = static_cast <unsigned >(std::abs (Val));
415+ unsigned ValLSB = countTrailingZeros (UVal, ZB_Width);
416+ // Chop off constant bits according to maximum log align
417+ unsigned NewLogAlign = std::max (ValLSB, LogAlign);
418+ return Alignment (NewLogAlign, UVal & ((1 << NewLogAlign) - 1 ));
419+ }
420+
368421/* **********************************************************************
369422 * getFromInstMap : get the alignment of a value, direct from InstMap if
370423 * found else return Unknown, Alignment(0, 0)
0 commit comments