Skip to content

Commit 7cbb107

Browse files
committed
[Attributor][FIX] Validate the type for AAValueConstantRange as needed
Due to the genericValueTraversal we might visit values for which we did not create an AAValueConstantRange object, e.g., as they are behind a PHI or select or call with `returned` argument. As a consequence we need to validate the types as we are about to query AAValueConstantRange for operands.
1 parent 01b02a7 commit 7cbb107

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

llvm/lib/Transforms/IPO/Attributor.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6266,28 +6266,15 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
62666266
return;
62676267
}
62686268

6269-
if (auto *I = dyn_cast<Instruction>(&V))
6270-
if (isa<BinaryOperator>(I) || isa<CmpInst>(I)) {
6271-
Value *LHS = I->getOperand(0);
6272-
Value *RHS = I->getOperand(1);
6273-
6274-
if (LHS->getType()->isIntegerTy() && RHS->getType()->isIntegerTy())
6275-
return;
6276-
}
6277-
6269+
if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
6270+
return;
62786271
// If it is a load instruction with range metadata, use it.
62796272
if (LoadInst *LI = dyn_cast<LoadInst>(&V))
62806273
if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
62816274
intersectKnown(getConstantRangeFromMetadata(*RangeMD));
62826275
return;
62836276
}
62846277

6285-
// We handle casts in the updateImpl.
6286-
// TODO: Allow non integers as well.
6287-
if (CastInst *CI = dyn_cast<CastInst>(&V))
6288-
if (CI->getOperand(0)->getType()->isIntegerTy())
6289-
return;
6290-
62916278
// We can work with PHI and select instruction as we traverse their operands
62926279
// during update.
62936280
if (isa<SelectInst>(V) || isa<PHINode>(V))
@@ -6306,6 +6293,9 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
63066293
SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
63076294
Value *LHS = BinOp->getOperand(0);
63086295
Value *RHS = BinOp->getOperand(1);
6296+
// TODO: Allow non integers as well.
6297+
if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
6298+
return false;
63096299

63106300
auto &LHSAA =
63116301
A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
@@ -6332,7 +6322,8 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
63326322
assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
63336323
// TODO: Allow non integers as well.
63346324
Value &OpV = *CastI->getOperand(0);
6335-
assert(OpV.getType()->isIntegerTy() && "Expected integer cast");
6325+
if (!OpV.getType()->isIntegerTy())
6326+
return false;
63366327

63376328
auto &OpAA =
63386329
A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(OpV));
@@ -6348,6 +6339,9 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
63486339
SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
63496340
Value *LHS = CmpI->getOperand(0);
63506341
Value *RHS = CmpI->getOperand(1);
6342+
// TODO: Allow non integers as well.
6343+
if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
6344+
return false;
63516345

63526346
auto &LHSAA =
63536347
A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));

llvm/test/Transforms/Attributor/range.ll

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,37 @@ entry:
11311131

11321132
; }
11331133

1134+
define i1 @f_fcmp(float %a, float %b) {
1135+
%r = fcmp uge float %a, %b
1136+
%s = select i1 %r, i1 %r, i1 0
1137+
ret i1 %s
1138+
}
1139+
define i1 @d_fcmp(double %a, double %b) {
1140+
%r = fcmp oeq double %a, %b
1141+
%s = select i1 %r, i1 %r, i1 0
1142+
ret i1 %s
1143+
}
1144+
define i1 @dp_icmp(double* %a, double* %b) {
1145+
%r = icmp sge double* %a, %b
1146+
%s = select i1 %r, i1 %r, i1 0
1147+
ret i1 %s
1148+
}
1149+
define i1 @ip_icmp(i8* %a, i8* %b) {
1150+
%r = icmp ult i8* %a, %b
1151+
%s = select i1 %r, i1 %r, i1 0
1152+
ret i1 %s
1153+
}
1154+
define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dpa, double* %dpb, i8* %ipa, i8* %ipb) {
1155+
%r1 = call i1 @f_fcmp(float %fa, float %fb)
1156+
%r2 = call i1 @d_fcmp(double %da, double %db)
1157+
%r3 = call i1 @dp_icmp(double* %dpa, double* %dpb)
1158+
%r4 = call i1 @ip_icmp(i8* %ipa, i8* %ipb)
1159+
%o1 = or i1 %r1, %r2
1160+
%o2 = or i1 %r3, %r4
1161+
%o3 = or i1 %o1, %o2
1162+
ret i1 %o3
1163+
}
1164+
11341165
!0 = !{i32 0, i32 10}
11351166
!1 = !{i32 10, i32 100}
11361167
; CHECK: !0 = !{i32 0, i32 10}

0 commit comments

Comments
 (0)