This revision was automatically updated to reflect the committed changes.
Closed by commit rG464926ef4484: [HLSL] Disable integer promotion to avoid
int16_t being promoted to int for… (authored by python3kgae).
Changed prior to commit:
https://reviews.llvm.org/D133668?vs=469373&id=469387#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D133668/new/
https://reviews.llvm.org/D133668
Files:
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/CanonicalType.h
clang/include/clang/AST/Type.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/FormatString.cpp
clang/lib/AST/Type.cpp
clang/lib/CodeGen/CGExprScalar.cpp
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaType.cpp
clang/test/CodeGenHLSL/builtins/abs.hlsl
clang/test/CodeGenHLSL/no_int_promotion.hlsl
clang/test/SemaHLSL/BitInt128.hlsl
Index: clang/test/SemaHLSL/BitInt128.hlsl
===================================================================
--- /dev/null
+++ clang/test/SemaHLSL/BitInt128.hlsl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s -verify
+
+// expected-error@+1 {{_BitInt is not supported on this target}}
+_BitInt(128) i128;
+
+// expected-error@+1 {{_BitInt is not supported on this target}}
+unsigned _BitInt(128) u128;
Index: clang/test/CodeGenHLSL/no_int_promotion.hlsl
===================================================================
--- /dev/null
+++ clang/test/CodeGenHLSL/no_int_promotion.hlsl
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -D__HLSL_ENABLE_16_BIT \
+// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s
+
+// FIXME: add test for char/int8_t/uint8_t when these types are supported in HLSL.
+// See https://github.com/llvm/llvm-project/issues/58453.
+
+// Make sure generate i16 add.
+// CHECK: add nsw i16 %
+int16_t add(int16_t a, int16_t b) {
+ return a + b;
+}
+// CHECK: define noundef <2 x i16> @
+// CHECK: add <2 x i16>
+int16_t2 add(int16_t2 a, int16_t2 b) {
+ return a + b;
+}
+// CHECK: define noundef <3 x i16> @
+// CHECK: add <3 x i16>
+int16_t3 add(int16_t3 a, int16_t3 b) {
+ return a + b;
+}
+// CHECK: define noundef <4 x i16> @
+// CHECK: add <4 x i16>
+int16_t4 add(int16_t4 a, int16_t4 b) {
+ return a + b;
+}
+// CHECK: define noundef i16 @
+// CHECK: add i16 %
+uint16_t add(uint16_t a, uint16_t b) {
+ return a + b;
+}
+// CHECK: define noundef <2 x i16> @
+// CHECK: add <2 x i16>
+uint16_t2 add(uint16_t2 a, uint16_t2 b) {
+ return a + b;
+}
+// CHECK: define noundef <3 x i16> @
+// CHECK: add <3 x i16>
+uint16_t3 add(uint16_t3 a, uint16_t3 b) {
+ return a + b;
+}
+// CHECK: define noundef <4 x i16> @
+// CHECK: add <4 x i16>
+uint16_t4 add(uint16_t4 a, uint16_t4 b) {
+ return a + b;
+}
Index: clang/test/CodeGenHLSL/builtins/abs.hlsl
===================================================================
--- clang/test/CodeGenHLSL/builtins/abs.hlsl
+++ clang/test/CodeGenHLSL/builtins/abs.hlsl
@@ -7,9 +7,8 @@
using hlsl::abs;
-// CHECK: define noundef signext i16 @
-// FIXME: int16_t is promoted to i32 now. Change to abs.i16 once it is fixed.
-// CHECK: call i32 @llvm.abs.i32(
+// CHECK: define noundef i16 @
+// CHECK: call i16 @llvm.abs.i16(
int16_t test_abs_int16_t ( int16_t p0 ) {
return abs ( p0 );
}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -5457,10 +5457,10 @@
D.setInvalidType();
}
} else if (!FTI.hasPrototype) {
- if (ParamTy->isPromotableIntegerType()) {
+ if (Context.isPromotableIntegerType(ParamTy)) {
ParamTy = Context.getPromotedIntegerType(ParamTy);
Param->setKNRPromoted(true);
- } else if (const BuiltinType* BTy = ParamTy->getAs<BuiltinType>()) {
+ } else if (const BuiltinType *BTy = ParamTy->getAs<BuiltinType>()) {
if (BTy->getKind() == BuiltinType::Float) {
ParamTy = Context.DoubleTy;
Param->setKNRPromoted(true);
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2168,9 +2168,9 @@
// int can represent all the values of the source type; otherwise,
// the source rvalue can be converted to an rvalue of type unsigned
// int (C++ 4.5p1).
- if (FromType->isPromotableIntegerType() && !FromType->isBooleanType() &&
+ if (Context.isPromotableIntegerType(FromType) && !FromType->isBooleanType() &&
!FromType->isEnumeralType()) {
- if (// We can promote any signed, promotable integer type to an int
+ if ( // We can promote any signed, promotable integer type to an int
(FromType->isSignedIntegerType() ||
// We can promote any unsigned integer type whose size is
// less than int to an int.
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -2934,7 +2934,7 @@
// Compute the type of the integer literals.
QualType PromotedCharTy = CharTy;
- if (CharTy->isPromotableIntegerType())
+ if (Context.isPromotableIntegerType(CharTy))
PromotedCharTy = Context.getPromotedIntegerType(CharTy);
unsigned PromotedCharTyWidth = Context.getTypeSize(PromotedCharTy);
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -839,7 +839,7 @@
E = ImpCastExprToType(E, PTy, CK_IntegralCast).get();
return E;
}
- if (Ty->isPromotableIntegerType()) {
+ if (Context.isPromotableIntegerType(Ty)) {
QualType PT = Context.getPromotedIntegerType(Ty);
E = ImpCastExprToType(E, PT, CK_IntegralCast).get();
return E;
@@ -1558,7 +1558,7 @@
// Apply unary and bitfield promotions to the LHS's type.
QualType LHSUnpromotedType = LHSType;
- if (LHSType->isPromotableIntegerType())
+ if (Context.isPromotableIntegerType(LHSType))
LHSType = Context.getPromotedIntegerType(LHSType);
QualType LHSBitfieldPromoteTy = Context.isPromotableBitField(LHS.get());
if (!LHSBitfieldPromoteTy.isNull())
@@ -11259,7 +11259,7 @@
QualType LHSTy = Context.isPromotableBitField(LHS.get());
if (LHSTy.isNull()) {
LHSTy = LHS.get()->getType();
- if (LHSTy->isPromotableIntegerType())
+ if (Context.isPromotableIntegerType(LHSTy))
LHSTy = Context.getPromotedIntegerType(LHSTy);
}
*CompLHSTy = LHSTy;
@@ -12278,7 +12278,7 @@
// We can't use `CK_IntegralCast` when the underlying type is 'bool', so we
// promote the boolean type, and all other promotable integer types, to
// avoid this.
- if (IntType->isPromotableIntegerType())
+ if (S.Context.isPromotableIntegerType(IntType))
IntType = S.Context.getPromotedIntegerType(IntType);
LHS = S.ImpCastExprToType(LHS.get(), IntType, CK_IntegralCast);
@@ -15557,7 +15557,7 @@
if (T.isNull() || T->isDependentType())
return false;
- if (!T->isPromotableIntegerType())
+ if (!Ctx.isPromotableIntegerType(T))
return true;
return Ctx.getIntWidth(T) >= Ctx.getIntWidth(Ctx.IntTy);
@@ -16650,7 +16650,7 @@
// Check for va_arg where arguments of the given type will be promoted
// (i.e. this va_arg is guaranteed to have undefined behavior).
QualType PromoteType;
- if (TInfo->getType()->isPromotableIntegerType()) {
+ if (Context.isPromotableIntegerType(TInfo->getType())) {
PromoteType = Context.getPromotedIntegerType(TInfo->getType());
// [cstdarg.syn]p1 defers the C++ behavior to what the C standard says,
// and C2x 7.16.1.1p2 says, in part:
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16499,7 +16499,7 @@
else
ED->setIntegerType(QualType(EnumUnderlying.get<const Type *>(), 0));
QualType EnumTy = ED->getIntegerType();
- ED->setPromotionType(EnumTy->isPromotableIntegerType()
+ ED->setPromotionType(Context.isPromotableIntegerType(EnumTy)
? Context.getPromotedIntegerType(EnumTy)
: EnumTy);
}
@@ -17125,7 +17125,7 @@
else
ED->setIntegerType(QualType(EnumUnderlying.get<const Type *>(), 0));
QualType EnumTy = ED->getIntegerType();
- ED->setPromotionType(EnumTy->isPromotableIntegerType()
+ ED->setPromotionType(Context.isPromotableIntegerType(EnumTy)
? Context.getPromotedIntegerType(EnumTy)
: EnumTy);
assert(ED->isComplete() && "enum with type should be complete");
@@ -19357,7 +19357,7 @@
// target, promote that type instead of analyzing the enumerators.
if (Enum->isComplete()) {
BestType = Enum->getIntegerType();
- if (BestType->isPromotableIntegerType())
+ if (Context.isPromotableIntegerType(BestType))
BestPromotionType = Context.getPromotedIntegerType(BestType);
else
BestPromotionType = BestType;
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -7179,7 +7179,7 @@
Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
// Promotable integers are UB, but enumerations need a bit of
// extra checking to see what their promotable type actually is.
- if (!Type->isPromotableIntegerType())
+ if (!Context.isPromotableIntegerType(Type))
return false;
if (!Type->isEnumeralType())
return true;
@@ -10047,7 +10047,7 @@
// It's an integer promotion if the destination type is the promoted
// source type.
if (ICE->getCastKind() == CK_IntegralCast &&
- From->isPromotableIntegerType() &&
+ S.Context.isPromotableIntegerType(From) &&
S.Context.getPromotedIntegerType(From) == To)
return true;
// Look through vector types, since we do default argument promotion for
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -106,7 +106,7 @@
}
bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
- if (Ty->isPromotableIntegerType())
+ if (getContext().isPromotableIntegerType(Ty))
return true;
if (const auto *EIT = Ty->getAs<BitIntType>())
@@ -4588,7 +4588,7 @@
Ty = EnumTy->getDecl()->getIntegerType();
// Promotable integer types are required to be promoted by the ABI.
- if (Ty->isPromotableIntegerType())
+ if (getContext().isPromotableIntegerType(Ty))
return true;
if (!Is64Bit)
Index: clang/lib/CodeGen/CGExprScalar.cpp
===================================================================
--- clang/lib/CodeGen/CGExprScalar.cpp
+++ clang/lib/CodeGen/CGExprScalar.cpp
@@ -159,7 +159,7 @@
return llvm::None;
QualType BaseTy = Base->getType();
- if (!BaseTy->isPromotableIntegerType() ||
+ if (!Ctx.isPromotableIntegerType(BaseTy) ||
Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType()))
return llvm::None;
@@ -2612,7 +2612,7 @@
} else if (type->isIntegerType()) {
QualType promotedType;
bool canPerformLossyDemotionCheck = false;
- if (type->isPromotableIntegerType()) {
+ if (CGF.getContext().isPromotableIntegerType(type)) {
promotedType = CGF.getContext().getPromotedIntegerType(type);
assert(promotedType != type && "Shouldn't promote to the same type.");
canPerformLossyDemotionCheck = true;
Index: clang/lib/AST/Type.cpp
===================================================================
--- clang/lib/AST/Type.cpp
+++ clang/lib/AST/Type.cpp
@@ -2778,39 +2778,6 @@
return false;
}
-bool Type::isPromotableIntegerType() const {
- if (const auto *BT = getAs<BuiltinType>())
- switch (BT->getKind()) {
- case BuiltinType::Bool:
- case BuiltinType::Char_S:
- case BuiltinType::Char_U:
- case BuiltinType::SChar:
- case BuiltinType::UChar:
- case BuiltinType::Short:
- case BuiltinType::UShort:
- case BuiltinType::WChar_S:
- case BuiltinType::WChar_U:
- case BuiltinType::Char8:
- case BuiltinType::Char16:
- case BuiltinType::Char32:
- return true;
- default:
- return false;
- }
-
- // Enumerated types are promotable to their compatible integer types
- // (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2).
- if (const auto *ET = getAs<EnumType>()){
- if (this->isDependentType() || ET->getDecl()->getPromotionType().isNull()
- || ET->getDecl()->isScoped())
- return false;
-
- return true;
- }
-
- return false;
-}
-
bool Type::isSpecifierType() const {
// Note that this intentionally does not use the canonical type.
switch (getTypeClass()) {
Index: clang/lib/AST/FormatString.cpp
===================================================================
--- clang/lib/AST/FormatString.cpp
+++ clang/lib/AST/FormatString.cpp
@@ -510,7 +510,7 @@
if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
return Match;
- QualType PromoArg = argTy->isPromotableIntegerType()
+ QualType PromoArg = C.isPromotableIntegerType(argTy)
? C.getPromotedIntegerType(argTy)
: argTy;
PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -1894,6 +1894,44 @@
return getTypeInfoInChars(T.getTypePtr());
}
+bool ASTContext::isPromotableIntegerType(QualType T) const {
+ // HLSL doesn't promote all small integer types to int, it
+ // just uses the rank-based promotion rules for all types.
+ if (getLangOpts().HLSL)
+ return false;
+
+ if (const auto *BT = T->getAs<BuiltinType>())
+ switch (BT->getKind()) {
+ case BuiltinType::Bool:
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+ case BuiltinType::Short:
+ case BuiltinType::UShort:
+ case BuiltinType::WChar_S:
+ case BuiltinType::WChar_U:
+ case BuiltinType::Char8:
+ case BuiltinType::Char16:
+ case BuiltinType::Char32:
+ return true;
+ default:
+ return false;
+ }
+
+ // Enumerated types are promotable to their compatible integer types
+ // (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2).
+ if (const auto *ET = T->getAs<EnumType>()) {
+ if (T->isDependentType() || ET->getDecl()->getPromotionType().isNull() ||
+ ET->getDecl()->isScoped())
+ return false;
+
+ return true;
+ }
+
+ return false;
+}
+
bool ASTContext::isAlignmentRequired(const Type *T) const {
return getTypeInfo(T).AlignRequirement != AlignRequirementKind::None;
}
@@ -7128,7 +7166,7 @@
/// integer type.
QualType ASTContext::getPromotedIntegerType(QualType Promotable) const {
assert(!Promotable.isNull());
- assert(Promotable->isPromotableIntegerType());
+ assert(isPromotableIntegerType(Promotable));
if (const auto *ET = Promotable->getAs<EnumType>())
return ET->getDecl()->getPromotionType();
@@ -10329,7 +10367,7 @@
return {};
}
- if (paramTy->isPromotableIntegerType() ||
+ if (isPromotableIntegerType(paramTy) ||
getCanonicalType(paramTy).getUnqualifiedType() == FloatTy)
return {};
}
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
@@ -676,14 +676,14 @@
assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
// Always perform integer promotion before checking type equality.
// Otherwise, e.g. (bool) a + (bool) b could trigger a backend assertion
- if (LTy->isPromotableIntegerType()) {
+ if (Ctx.isPromotableIntegerType(LTy)) {
QualType NewTy = Ctx.getPromotedIntegerType(LTy);
uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
LHS = (*doCast)(Solver, LHS, NewTy, NewBitWidth, LTy, LBitWidth);
LTy = NewTy;
LBitWidth = NewBitWidth;
}
- if (RTy->isPromotableIntegerType()) {
+ if (Ctx.isPromotableIntegerType(RTy)) {
QualType NewTy = Ctx.getPromotedIntegerType(RTy);
uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
RHS = (*doCast)(Solver, RHS, NewTy, NewBitWidth, RTy, RBitWidth);
Index: clang/include/clang/AST/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -2471,9 +2471,6 @@
/// removing any typedefs, typeofs, etc., as well as any qualifiers.
const Type *getUnqualifiedDesugaredType() const;
- /// More type predicates useful for type checking/promotion
- bool isPromotableIntegerType() const; // C99 6.3.1.1p2
-
/// Return true if this is an integer type that is
/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
/// or an enum decl which has a signed representation.
Index: clang/include/clang/AST/CanonicalType.h
===================================================================
--- clang/include/clang/AST/CanonicalType.h
+++ clang/include/clang/AST/CanonicalType.h
@@ -305,7 +305,6 @@
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -2380,6 +2380,9 @@
bool isAlignmentRequired(const Type *T) const;
bool isAlignmentRequired(QualType T) const;
+ /// More type predicates useful for type checking/promotion
+ bool isPromotableIntegerType(QualType T) const; // C99 6.3.1.1p2
+
/// Return the "preferred" alignment of the specified type \p T for
/// the current target, in bits.
///
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits