[llvm] [IR] Add new Range attribute using new ConstantRange Attribute type (PR #83171)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 6 09:17:21 PST 2024


================
@@ -889,13 +909,30 @@ void ModuleBitcodeWriter::writeAttributeGroupTable() {
           Record.append(Val.begin(), Val.end());
           Record.push_back(0);
         }
-      } else {
-        assert(Attr.isTypeAttribute());
+      } else if (Attr.isTypeAttribute()) {
         Type *Ty = Attr.getValueAsType();
         Record.push_back(Ty ? 6 : 5);
         Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
         if (Ty)
           Record.push_back(VE.getTypeID(Attr.getValueAsType()));
+      } else {
+        assert(Attr.isConstantRangeAttribute());
+        ConstantRange Range = Attr.getValueAsConstantRange();
+        bool WideAPInt = Range.getBitWidth() > 64;
+        Record.push_back(WideAPInt ? 8 : 7);
+        Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
+        Record.push_back(Range.getBitWidth());
+        if (WideAPInt) {
+          const APInt &Lower = Range.getLower();
+          Record.push_back(Lower.getActiveWords());
+          emitWideAPInt(Record, Lower);
+          const APInt &Upper = Range.getUpper();
+          Record.push_back(Upper.getActiveWords());
+          emitWideAPInt(Record, Upper);
+        } else {
+          emitSignedInt64(Record, *Range.getLower().getRawData());
+          emitSignedInt64(Record, *Range.getUpper().getRawData());
+        }
----------------
nikic wrote:

It would be good to have a ConstantRange encoding that can be reused for other purposes as well. The way this is implemented now this will be a bit hard, as the wide distinction is part of the attribute kind.

I have some local changes that also needed this, and these are the implementations I used:
```
// BitcodeWriter
static void emitConstantRange(SmallVectorImpl<uint64_t> &Record,
                              const ConstantRange &CR) {
  unsigned BitWidth = CR.getBitWidth();
  Record.push_back(BitWidth);
  if (BitWidth > 64) {
    Record.push_back(CR.getLower().getActiveWords() |
        (uint64_t(CR.getUpper().getActiveWords()) << 32));
    emitWideAPInt(Record, CR.getLower());
    emitWideAPInt(Record, CR.getUpper());
  } else {
    emitSignedInt64(Record, CR.getLower().getSExtValue());
    emitSignedInt64(Record, CR.getUpper().getSExtValue());
  }
}

// BitcodeReader
Expected<ConstantRange> readConstantRange(ArrayRef<uint64_t> Record,
                                          unsigned &OpNum) {
  if (Record.size() - OpNum < 3)
    return error("Too few records for range");
  unsigned BitWidth = Record[OpNum++];
  if (BitWidth > 64) {
    unsigned LowerActiveWords = Record[OpNum];
    unsigned UpperActiveWords = Record[OpNum++] >> 32;
    if (Record.size() - OpNum < LowerActiveWords + UpperActiveWords)
      return error("Too few records for range");
    APInt Lower =
        readWideAPInt(ArrayRef(&Record[OpNum], LowerActiveWords), BitWidth);
    OpNum += LowerActiveWords;
    APInt Upper =
        readWideAPInt(ArrayRef(&Record[OpNum], UpperActiveWords), BitWidth);
    OpNum += UpperActiveWords;
    return ConstantRange(Lower, Upper);
  } else {        
    int64_t Start = BitcodeReader::decodeSignRotatedValue(Record[OpNum++]);
    int64_t End = BitcodeReader::decodeSignRotatedValue(Record[OpNum++]);
    return ConstantRange(APInt(BitWidth, Start), APInt(BitWidth, End));
  }
} 
```

https://github.com/llvm/llvm-project/pull/83171


More information about the llvm-commits mailing list