[LVI] Use !range metadata for supported intrinsics
authorNikita Popov <npopov@redhat.com>
Thu, 26 Jan 2023 14:09:48 +0000 (15:09 +0100)
committerNikita Popov <npopov@redhat.com>
Thu, 26 Jan 2023 14:09:48 +0000 (15:09 +0100)
Even if the intrinsic is supported by ConstantRange, we should
still make use of !range metadata. This doesn't matter much now,
but is important if we want to support ctlz style intrinsics,
which always have KnownBits-based !range metadata attached, which
might be better than what we can compute using ranges.

llvm/lib/Analysis/LazyValueInfo.cpp
llvm/test/Transforms/CorrelatedValuePropagation/range.ll

index f1587ce..16d9ad7 100644 (file)
@@ -990,10 +990,11 @@ LazyValueInfoImpl::solveBlockValueOverflowIntrinsic(WithOverflowInst *WO,
 
 std::optional<ValueLatticeElement>
 LazyValueInfoImpl::solveBlockValueIntrinsic(IntrinsicInst *II, BasicBlock *BB) {
+  ValueLatticeElement MetadataVal = getFromRangeMetadata(II);
   if (!ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
     LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
                       << "' - unknown intrinsic.\n");
-    return getFromRangeMetadata(II);
+    return MetadataVal;
   }
 
   SmallVector<ConstantRange, 2> OpRanges;
@@ -1004,8 +1005,9 @@ LazyValueInfoImpl::solveBlockValueIntrinsic(IntrinsicInst *II, BasicBlock *BB) {
     OpRanges.push_back(*Range);
   }
 
-  return ValueLatticeElement::getRange(
-      ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges));
+  return intersect(ValueLatticeElement::getRange(ConstantRange::intrinsic(
+                       II->getIntrinsicID(), OpRanges)),
+                   MetadataVal);
 }
 
 std::optional<ValueLatticeElement>
index 458ecae..26b31ce 100644 (file)
@@ -950,8 +950,7 @@ define i1 @supported_intrinsic_range(i16 %x) {
 ; CHECK-LABEL: @supported_intrinsic_range(
 ; CHECK-NEXT:    [[ABS:%.*]] = call i16 @llvm.abs.i16(i16 [[X:%.*]], i1 false), !range [[RNG5]]
 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i16 [[ABS]] to i8
-; CHECK-NEXT:    [[RES:%.*]] = icmp ult i8 [[TRUNC]], 8
-; CHECK-NEXT:    ret i1 [[RES]]
+; CHECK-NEXT:    ret i1 true
 ;
   %abs = call i16 @llvm.abs.i16(i16 %x, i1 false), !range !{i16 0, i16 8}
   %trunc = trunc i16 %abs to i8