Skip to content

Commit f990745

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merge upstream LLVM into amd-gfx12
2 parents d50c27f + 46526f8 commit f990745

File tree

31 files changed

+1035
-1522
lines changed

31 files changed

+1035
-1522
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,6 +2911,28 @@ def CIR_BitCtzOp : CIR_BitZeroCountOpBase<"ctz",
29112911
}];
29122912
}
29132913

2914+
def CIR_BitFfsOp : CIR_BitOpBase<"ffs", CIR_SIntOfWidths<[32, 64]>> {
2915+
let summary = "Get the position of the least significant 1-bit in input";
2916+
let description = [{
2917+
Compute the 1-based position of the least significant 1-bit of the input.
2918+
2919+
The input integer must be a signed integer. The `cir.ffs` operation returns
2920+
one plus the index of the least significant 1-bit of the input signed
2921+
integer. If the input integer is 0, `cir.ffs` yields 0.
2922+
2923+
Example:
2924+
2925+
```mlir
2926+
!s32i = !cir.int<s, 32>
2927+
2928+
// %0 = 0x0010_1000
2929+
%0 = cir.const #cir.int<40> : !s32i
2930+
// #1 will be 4 since the 4th least significant bit is 1.
2931+
%1 = cir.ffs %0 : !s32i
2932+
```
2933+
}];
2934+
}
2935+
29142936
def CIR_BitParityOp : CIR_BitOpBase<"parity", CIR_UIntOfWidths<[32, 64]>> {
29152937
let summary = "Get the parity of input";
29162938
let description = [{

clang/lib/AST/ASTStructuralEquivalence.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,29 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
870870
else if (T1->getTypeClass() == Type::FunctionNoProto &&
871871
T2->getTypeClass() == Type::FunctionProto)
872872
TC = Type::FunctionNoProto;
873-
else
873+
else if (Context.LangOpts.C23 && !Context.StrictTypeSpelling &&
874+
(T1->getTypeClass() == Type::Enum ||
875+
T2->getTypeClass() == Type::Enum)) {
876+
// In C23, if not being strict about token equivalence, we need to handle
877+
// the case where one type is an enumeration and the other type is an
878+
// integral type.
879+
//
880+
// C23 6.7.3.3p16: The enumerated type is compatible with the underlying
881+
// type of the enumeration.
882+
//
883+
// Treat the enumeration as its underlying type and use the builtin type
884+
// class comparison.
885+
if (T1->getTypeClass() == Type::Enum) {
886+
T1 = T1->getAs<EnumType>()->getDecl()->getIntegerType();
887+
if (!T2->isBuiltinType() || T1.isNull()) // Sanity check
888+
return false;
889+
} else if (T2->getTypeClass() == Type::Enum) {
890+
T2 = T2->getAs<EnumType>()->getDecl()->getIntegerType();
891+
if (!T1->isBuiltinType() || T2.isNull()) // Sanity check
892+
return false;
893+
}
894+
TC = Type::Builtin;
895+
} else
874896
return false;
875897
}
876898

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
190190
assert(!cir::MissingFeatures::builtinCheckKind());
191191
return emitBuiltinBitOp<cir::BitClzOp>(*this, e, /*poisonZero=*/true);
192192

193+
case Builtin::BI__builtin_ffs:
194+
case Builtin::BI__builtin_ffsl:
195+
case Builtin::BI__builtin_ffsll:
196+
return emitBuiltinBitOp<cir::BitFfsOp>(*this, e);
197+
193198
case Builtin::BI__builtin_parity:
194199
case Builtin::BI__builtin_parityl:
195200
case Builtin::BI__builtin_parityll:

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,6 +2295,15 @@ OpFoldResult BitCtzOp::fold(FoldAdaptor adaptor) {
22952295
getPoisonZero());
22962296
}
22972297

2298+
OpFoldResult BitFfsOp::fold(FoldAdaptor adaptor) {
2299+
return foldUnaryBitOp(adaptor.getInput(), [](const llvm::APInt &inputValue) {
2300+
unsigned trailingZeros = inputValue.countTrailingZeros();
2301+
unsigned result =
2302+
trailingZeros == inputValue.getBitWidth() ? 0 : trailingZeros + 1;
2303+
return llvm::APInt(inputValue.getBitWidth(), result);
2304+
});
2305+
}
2306+
22982307
OpFoldResult BitParityOp::fold(FoldAdaptor adaptor) {
22992308
return foldUnaryBitOp(adaptor.getInput(), [](const llvm::APInt &inputValue) {
23002309
return llvm::APInt(inputValue.getBitWidth(), inputValue.popcount() % 2);

clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ void CIRCanonicalizePass::runOnOperation() {
143143
if (isa<BrOp, BrCondOp, CastOp, ScopeOp, SwitchOp, SelectOp, UnaryOp,
144144
ComplexCreateOp, ComplexImagOp, ComplexRealOp, VecCmpOp,
145145
VecCreateOp, VecExtractOp, VecShuffleOp, VecShuffleDynamicOp,
146-
VecTernaryOp, BitClrsbOp, BitClzOp, BitCtzOp, BitParityOp,
146+
VecTernaryOp, BitClrsbOp, BitClzOp, BitCtzOp, BitFfsOp, BitParityOp,
147147
BitPopcountOp, BitReverseOp, ByteSwapOp, RotateOp>(op))
148148
ops.push_back(op);
149149
});

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,32 @@ mlir::LogicalResult CIRToLLVMBitCtzOpLowering::matchAndRewrite(
521521
return mlir::LogicalResult::success();
522522
}
523523

524+
mlir::LogicalResult CIRToLLVMBitFfsOpLowering::matchAndRewrite(
525+
cir::BitFfsOp op, OpAdaptor adaptor,
526+
mlir::ConversionPatternRewriter &rewriter) const {
527+
auto resTy = getTypeConverter()->convertType(op.getType());
528+
auto ctz = rewriter.create<mlir::LLVM::CountTrailingZerosOp>(
529+
op.getLoc(), resTy, adaptor.getInput(), /*is_zero_poison=*/true);
530+
531+
auto one = rewriter.create<mlir::LLVM::ConstantOp>(op.getLoc(), resTy, 1);
532+
auto ctzAddOne = rewriter.create<mlir::LLVM::AddOp>(op.getLoc(), ctz, one);
533+
534+
auto zeroInputTy = rewriter.create<mlir::LLVM::ConstantOp>(
535+
op.getLoc(), adaptor.getInput().getType(), 0);
536+
auto isZero = rewriter.create<mlir::LLVM::ICmpOp>(
537+
op.getLoc(),
538+
mlir::LLVM::ICmpPredicateAttr::get(rewriter.getContext(),
539+
mlir::LLVM::ICmpPredicate::eq),
540+
adaptor.getInput(), zeroInputTy);
541+
542+
auto zero = rewriter.create<mlir::LLVM::ConstantOp>(op.getLoc(), resTy, 0);
543+
auto res = rewriter.create<mlir::LLVM::SelectOp>(op.getLoc(), isZero, zero,
544+
ctzAddOne);
545+
rewriter.replaceOp(op, res);
546+
547+
return mlir::LogicalResult::success();
548+
}
549+
524550
mlir::LogicalResult CIRToLLVMBitParityOpLowering::matchAndRewrite(
525551
cir::BitParityOp op, OpAdaptor adaptor,
526552
mlir::ConversionPatternRewriter &rewriter) const {
@@ -2089,6 +2115,7 @@ void ConvertCIRToLLVMPass::runOnOperation() {
20892115
CIRToLLVMBitClrsbOpLowering,
20902116
CIRToLLVMBitClzOpLowering,
20912117
CIRToLLVMBitCtzOpLowering,
2118+
CIRToLLVMBitFfsOpLowering,
20922119
CIRToLLVMBitParityOpLowering,
20932120
CIRToLLVMBitPopcountOpLowering,
20942121
CIRToLLVMBitReverseOpLowering,

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ class CIRToLLVMBitCtzOpLowering
8484
mlir::ConversionPatternRewriter &) const override;
8585
};
8686

87+
class CIRToLLVMBitFfsOpLowering
88+
: public mlir::OpConversionPattern<cir::BitFfsOp> {
89+
public:
90+
using mlir::OpConversionPattern<cir::BitFfsOp>::OpConversionPattern;
91+
92+
mlir::LogicalResult
93+
matchAndRewrite(cir::BitFfsOp op, OpAdaptor,
94+
mlir::ConversionPatternRewriter &) const override;
95+
};
96+
8797
class CIRToLLVMBitParityOpLowering
8898
: public mlir::OpConversionPattern<cir::BitParityOp> {
8999
public:

clang/lib/Driver/ToolChain.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,10 @@ static void getAArch64MultilibFlags(const Driver &D,
191191
for (const auto &ArchInfo : AArch64::ArchInfos)
192192
if (FeatureSet.contains(ArchInfo->ArchFeature))
193193
ArchName = ArchInfo->Name;
194-
assert(!ArchName.empty() && "at least one architecture should be found");
195-
MArch.insert(MArch.begin(), ("-march=" + ArchName).str());
196-
Result.push_back(llvm::join(MArch, "+"));
194+
if (!ArchName.empty()) {
195+
MArch.insert(MArch.begin(), ("-march=" + ArchName).str());
196+
Result.push_back(llvm::join(MArch, "+"));
197+
}
197198

198199
const Arg *BranchProtectionArg =
199200
Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);

clang/lib/Headers/opencl-c.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18410,6 +18410,22 @@ intel_sub_group_avc_mce_convert_to_sic_result(
1841018410
#pragma OPENCL EXTENSION cl_intel_device_side_avc_motion_estimation : end
1841118411
#endif // cl_intel_device_side_avc_motion_estimation
1841218412

18413+
#if defined(cl_intel_bfloat16_conversions)
18414+
ushort __ovld intel_convert_bfloat16_as_ushort(float source);
18415+
ushort2 __ovld intel_convert_bfloat162_as_ushort2(float2 source);
18416+
ushort3 __ovld intel_convert_bfloat163_as_ushort3(float3 source);
18417+
ushort4 __ovld intel_convert_bfloat164_as_ushort4(float4 source);
18418+
ushort8 __ovld intel_convert_bfloat168_as_ushort8(float8 source);
18419+
ushort16 __ovld intel_convert_bfloat1616_as_ushort16(float16 source);
18420+
18421+
float __ovld intel_convert_as_bfloat16_float(ushort source);
18422+
float2 __ovld intel_convert_as_bfloat162_float2(ushort2 source);
18423+
float3 __ovld intel_convert_as_bfloat163_float3(ushort3 source);
18424+
float4 __ovld intel_convert_as_bfloat164_float4(ushort4 source);
18425+
float8 __ovld intel_convert_as_bfloat168_float8(ushort8 source);
18426+
float16 __ovld intel_convert_as_bfloat1616_float16(ushort16 source);
18427+
#endif // cl_intel_bfloat16_conversions
18428+
1841318429
#ifdef cl_amd_media_ops
1841418430
uint __ovld amd_bitalign(uint, uint, uint);
1841518431
uint2 __ovld amd_bitalign(uint2, uint2, uint2);

clang/test/C/C23/n3037.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,39 @@ _Static_assert(0 == _Generic(inner_anon_tagged.untagged, struct { int i; } : 1,
401401
// unions and structures are both RecordDecl objects, whereas EnumDecl is not).
402402
enum { E_Untagged1 } nontag_enum; // both-note {{previous definition is here}}
403403
_Static_assert(0 == _Generic(nontag_enum, enum { E_Untagged1 } : 1, default : 0)); // both-error {{redefinition of enumerator 'E_Untagged1'}}
404+
405+
// Test that enumerations are compatible with their underlying type, but still
406+
// diagnose when "same type" is required rather than merely "compatible type".
407+
enum E1 : int { e1 }; // Fixed underlying type
408+
enum E2 { e2 }; // Unfixed underlying type, defaults to int or unsigned int
409+
410+
struct GH149965_1 { int h; };
411+
// This typeof trick is used to get the underlying type of the enumeration in a
412+
// platform agnostic way.
413+
struct GH149965_2 { __typeof__(+(enum E2){}) h; };
414+
void gh149965(void) {
415+
extern struct GH149965_1 x1; // c17-note {{previous declaration is here}}
416+
extern struct GH149965_2 x2; // c17-note {{previous declaration is here}}
417+
418+
// Both the structure and the variable declarations are fine because only a
419+
// compatible type is required, not the same type, because the structures are
420+
// declared in different scopes.
421+
struct GH149965_1 { enum E1 h; };
422+
struct GH149965_2 { enum E2 h; };
423+
424+
extern struct GH149965_1 x1; // c17-error {{redeclaration of 'x1'}}
425+
extern struct GH149965_2 x2; // c17-error {{redeclaration of 'x2'}}
426+
427+
// However, in the same scope, the same type is required, not just compatible
428+
// types.
429+
// FIXME: this should be an error in both C17 and C23 mode.
430+
struct GH149965_3 { int h; }; // c17-note {{previous definition is here}}
431+
struct GH149965_3 { enum E1 h; }; // c17-error {{redefinition of 'GH149965_3'}}
432+
433+
// For Clang, the composite type after declaration merging is the enumeration
434+
// type rather than an integer type.
435+
enum E1 *eptr;
436+
[[maybe_unused]] __typeof__(x1.h) *ptr = eptr;
437+
enum E2 *eptr2;
438+
[[maybe_unused]] __typeof__(x2.h) *ptr2 = eptr2;
439+
}

0 commit comments

Comments
 (0)