Skip to content

Commit 34a4c58

Browse files
[clang] Rework hasBooleanRepresentation. (#136038)
This is a follow-up of 13aac46. This commit adjusts the implementation of `hasBooleanRepresentation` to be somewhat aligned to `hasIntegerRepresentation`. In particular vector of booleans should be handled in `hasBooleanRepresentation`, while `_Atomic(bool)` should not.
1 parent 68d89e9 commit 34a4c58

File tree

3 files changed

+25
-19
lines changed

3 files changed

+25
-19
lines changed

Diff for: clang/include/clang/AST/Type.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -2793,8 +2793,9 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
27932793
/// of some sort, e.g., it is a floating-point type or a vector thereof.
27942794
bool hasFloatingRepresentation() const;
27952795

2796-
/// Determine whether this type has a boolean representation
2797-
/// of some sort.
2796+
/// Determine whether this type has a boolean representation -- i.e., it is a
2797+
/// boolean type, an enum type whose underlying type is a boolean type, or a
2798+
/// vector of booleans.
27982799
bool hasBooleanRepresentation() const;
27992800

28002801
// Type Checking Functions: Check to see if this type is structurally the

Diff for: clang/lib/AST/Type.cpp

+9-10
Original file line numberDiff line numberDiff line change
@@ -2346,16 +2346,15 @@ bool Type::isArithmeticType() const {
23462346
}
23472347

23482348
bool Type::hasBooleanRepresentation() const {
2349-
if (isBooleanType())
2350-
return true;
2351-
2352-
if (const EnumType *ET = getAs<EnumType>())
2353-
return ET->getDecl()->getIntegerType()->isBooleanType();
2354-
2355-
if (const AtomicType *AT = getAs<AtomicType>())
2356-
return AT->getValueType()->hasBooleanRepresentation();
2357-
2358-
return false;
2349+
if (const auto *VT = dyn_cast<VectorType>(CanonicalType))
2350+
return VT->getElementType()->isBooleanType();
2351+
if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
2352+
return ET->getDecl()->isComplete() &&
2353+
ET->getDecl()->getIntegerType()->isBooleanType();
2354+
}
2355+
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
2356+
return IT->getNumBits() == 1;
2357+
return isBooleanType();
23592358
}
23602359

23612360
Type::ScalarTypeKind Type::getScalarTypeKind() const {

Diff for: clang/lib/CodeGen/CGExpr.cpp

+13-7
Original file line numberDiff line numberDiff line change
@@ -1920,7 +1920,7 @@ static bool getRangeForType(CodeGenFunction &CGF, QualType Ty,
19201920
llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
19211921
llvm::APInt Min, End;
19221922
if (!getRangeForType(*this, Ty, Min, End, CGM.getCodeGenOpts().StrictEnums,
1923-
Ty->hasBooleanRepresentation()))
1923+
Ty->hasBooleanRepresentation() && !Ty->isVectorType()))
19241924
return nullptr;
19251925

19261926
llvm::MDBuilder MDHelper(getLLVMContext());
@@ -1948,7 +1948,7 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
19481948
if (!HasBoolCheck && !HasEnumCheck)
19491949
return false;
19501950

1951-
bool IsBool = Ty->hasBooleanRepresentation() ||
1951+
bool IsBool = (Ty->hasBooleanRepresentation() && !Ty->isVectorType()) ||
19521952
NSAPI(CGM.getContext()).isObjCBOOLType(Ty);
19531953
bool NeedsBoolCheck = HasBoolCheck && IsBool;
19541954
bool NeedsEnumCheck = HasEnumCheck && Ty->getAs<EnumType>();
@@ -2068,11 +2068,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
20682068
/// by ConvertType) to its load/store type (as returned by
20692069
/// convertTypeForLoadStore).
20702070
llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
2071-
if (Ty->hasBooleanRepresentation() || Ty->isBitIntType()) {
2072-
llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType());
2073-
bool Signed = Ty->isSignedIntegerOrEnumerationType();
2074-
return Builder.CreateIntCast(Value, StoreTy, Signed, "storedv");
2075-
}
2071+
if (auto *AtomicTy = Ty->getAs<AtomicType>())
2072+
Ty = AtomicTy->getValueType();
20762073

20772074
if (Ty->isExtVectorBoolType()) {
20782075
llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType());
@@ -2088,13 +2085,22 @@ llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
20882085
Value = Builder.CreateBitCast(Value, StoreTy);
20892086
}
20902087

2088+
if (Ty->hasBooleanRepresentation() || Ty->isBitIntType()) {
2089+
llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType());
2090+
bool Signed = Ty->isSignedIntegerOrEnumerationType();
2091+
return Builder.CreateIntCast(Value, StoreTy, Signed, "storedv");
2092+
}
2093+
20912094
return Value;
20922095
}
20932096

20942097
/// Converts a scalar value from its load/store type (as returned
20952098
/// by convertTypeForLoadStore) to its primary IR type (as returned
20962099
/// by ConvertType).
20972100
llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
2101+
if (auto *AtomicTy = Ty->getAs<AtomicType>())
2102+
Ty = AtomicTy->getValueType();
2103+
20982104
if (Ty->isPackedVectorBoolType(getContext())) {
20992105
const auto *RawIntTy = Value->getType();
21002106

0 commit comments

Comments
 (0)