Skip to content

Commit 6e504d6

Browse files
committed
[ValueTracking] Handle constant exprs in isKnownNonZero()
Handle constant expressions by falling through to the general operator-based code. In particular, this adds support for bitcast and GEP expressions.
1 parent 0d30e92 commit 6e504d6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+262
-252
lines changed

clang/test/CodeGenCXX/RelativeVTablesABI/dynamic-cast.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// CHECK-NEXT: br i1 [[isnull]], label %[[dynamic_cast_end:[a-z0-9._]+]], label %[[dynamic_cast_notnull:[a-z0-9._]+]]
1616
// CHECK: [[dynamic_cast_notnull]]:
1717
// CHECK-NEXT: [[a:%[0-9]+]] = bitcast %class.A* %a to i8*
18-
// CHECK-NEXT: [[as_b:%[0-9]+]] = tail call i8* @__dynamic_cast(i8* nonnull [[a]], i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*), i64 0)
18+
// CHECK-NEXT: [[as_b:%[0-9]+]] = tail call i8* @__dynamic_cast(i8* nonnull [[a]], i8* nonnull bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* nonnull bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*), i64 0)
1919
// CHECK-NEXT: [[b:%[0-9]+]] = bitcast i8* [[as_b]] to %class.B*
2020
// CHECK-NEXT: br label %[[dynamic_cast_end]]
2121
// CHECK: [[dynamic_cast_end]]:

clang/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ T* test0() { return dynamic_cast<T*>((B*)0); }
1313
T* test1(V* x) { return &dynamic_cast<T&>(*x); }
1414
// CHECK-LABEL: define dso_local noundef %struct.T* @"?test1@@YAPAUT@@PAUV@@@Z"(%struct.V* noundef %x)
1515
// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
16-
// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
16+
// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* nonnull bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* nonnull bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
1717
// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
1818
// CHECK-NEXT: ret %struct.T* [[RET]]
1919

@@ -25,7 +25,7 @@ T* test2(A* x) { return &dynamic_cast<T&>(*x); }
2525
// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
2626
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
2727
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[VBOFFS]]
28-
// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
28+
// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* nonnull bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* nonnull bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
2929
// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
3030
// CHECK-NEXT: ret %struct.T* [[RET]]
3131

@@ -39,14 +39,14 @@ T* test3(B* x) { return &dynamic_cast<T&>(*x); }
3939
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
4040
// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
4141
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[DELTA]]
42-
// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
42+
// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* nonnull bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* nonnull bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
4343
// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
4444
// CHECK-NEXT: ret %struct.T* [[RET]]
4545

4646
T* test4(V* x) { return dynamic_cast<T*>(x); }
4747
// CHECK-LABEL: define dso_local noundef %struct.T* @"?test4@@YAPAUT@@PAUV@@@Z"(%struct.V* noundef %x)
4848
// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
49-
// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
49+
// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* nonnull bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* nonnull bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
5050
// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
5151
// CHECK-NEXT: ret %struct.T* [[RET]]
5252

clang/test/CodeGenCXX/microsoft-abi-typeid.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ extern int b;
1212
A* fn();
1313

1414
const std::type_info* test0_typeid() { return &typeid(int); }
15-
// CHECK-LABEL: define dso_local noundef %struct.type_info* @"?test0_typeid@@YAPBUtype_info@@XZ"()
15+
// CHECK-LABEL: define dso_local noundef nonnull %struct.type_info* @"?test0_typeid@@YAPBUtype_info@@XZ"()
1616
// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor2* @"??_R0H@8" to %struct.type_info*)
1717

1818
const std::type_info* test1_typeid() { return &typeid(A); }
19-
// CHECK-LABEL: define dso_local noundef %struct.type_info* @"?test1_typeid@@YAPBUtype_info@@XZ"()
19+
// CHECK-LABEL: define dso_local noundef nonnull %struct.type_info* @"?test1_typeid@@YAPBUtype_info@@XZ"()
2020
// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to %struct.type_info*)
2121

2222
const std::type_info* test2_typeid() { return &typeid(&a); }
23-
// CHECK-LABEL: define dso_local noundef %struct.type_info* @"?test2_typeid@@YAPBUtype_info@@XZ"()
23+
// CHECK-LABEL: define dso_local noundef nonnull %struct.type_info* @"?test2_typeid@@YAPBUtype_info@@XZ"()
2424
// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"??_R0PAUA@@@8" to %struct.type_info*)
2525

2626
const std::type_info* test3_typeid() { return &typeid(*fn()); }
@@ -41,15 +41,15 @@ const std::type_info* test3_typeid() { return &typeid(*fn()); }
4141
// CHECK-NEXT: ret %struct.type_info* [[RET]]
4242

4343
const std::type_info* test4_typeid() { return &typeid(b); }
44-
// CHECK: define dso_local noundef %struct.type_info* @"?test4_typeid@@YAPBUtype_info@@XZ"()
44+
// CHECK: define dso_local noundef nonnull %struct.type_info* @"?test4_typeid@@YAPBUtype_info@@XZ"()
4545
// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor2* @"??_R0H@8" to %struct.type_info*)
4646

4747
const std::type_info* test5_typeid() { return &typeid(v); }
48-
// CHECK: define dso_local noundef %struct.type_info* @"?test5_typeid@@YAPBUtype_info@@XZ"()
48+
// CHECK: define dso_local noundef nonnull %struct.type_info* @"?test5_typeid@@YAPBUtype_info@@XZ"()
4949
// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to %struct.type_info*)
5050

5151
const std::type_info *test6_typeid() { return &typeid((V &)v); }
52-
// CHECK: define dso_local noundef %struct.type_info* @"?test6_typeid@@YAPBUtype_info@@XZ"()
52+
// CHECK: define dso_local noundef nonnull %struct.type_info* @"?test6_typeid@@YAPBUtype_info@@XZ"()
5353
// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to %struct.type_info*)
5454

5555
namespace PR26329 {

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,16 +2481,6 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
24812481
// Must be non-zero due to null test above.
24822482
return true;
24832483

2484-
if (auto *CE = dyn_cast<ConstantExpr>(C)) {
2485-
// See the comment for IntToPtr/PtrToInt instructions below.
2486-
if (CE->getOpcode() == Instruction::IntToPtr ||
2487-
CE->getOpcode() == Instruction::PtrToInt)
2488-
if (Q.DL.getTypeSizeInBits(CE->getOperand(0)->getType())
2489-
.getFixedSize() <=
2490-
Q.DL.getTypeSizeInBits(CE->getType()).getFixedSize())
2491-
return isKnownNonZero(CE->getOperand(0), Depth, Q);
2492-
}
2493-
24942484
// For constant vectors, check that all elements are undefined or known
24952485
// non-zero to determine that the whole vector is known non-zero.
24962486
if (auto *VecTy = dyn_cast<FixedVectorType>(C->getType())) {
@@ -2513,7 +2503,10 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
25132503
if (!GV->isAbsoluteSymbolRef() && !GV->hasExternalWeakLinkage() &&
25142504
GV->getType()->getAddressSpace() == 0)
25152505
return true;
2516-
} else
2506+
}
2507+
2508+
// For constant expressions, fall through to the Operator code below.
2509+
if (!isa<ConstantExpr>(V))
25172510
return false;
25182511
}
25192512

@@ -2529,7 +2522,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
25292522
}
25302523
}
25312524

2532-
if (isKnownNonZeroFromAssume(V, Q))
2525+
if (!isa<Constant>(V) && isKnownNonZeroFromAssume(V, Q))
25332526
return true;
25342527

25352528
// Some of the tests below are recursive, so bail out if we hit the limit.
@@ -2565,7 +2558,8 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
25652558
}
25662559
}
25672560

2568-
if (isKnownNonNullFromDominatingCondition(V, Q.CxtI, Q.DT))
2561+
if (!isa<Constant>(V) &&
2562+
isKnownNonNullFromDominatingCondition(V, Q.CxtI, Q.DT))
25692563
return true;
25702564

25712565
const Operator *I = dyn_cast<Operator>(V);

0 commit comments

Comments
 (0)