Skip to content

Commit f473089

Browse files
authored
merge main into amd-staging (#597)
2 parents 662749c + b51530b commit f473089

File tree

166 files changed

+66920
-63577
lines changed

Some content is hidden

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

166 files changed

+66920
-63577
lines changed

clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -456,17 +456,15 @@ class SMTConv {
456456
llvm::SMTExprRef OperandExp =
457457
getSymExpr(Solver, Ctx, USE->getOperand(), &OperandTy, hasComparison);
458458

459-
if (const BinarySymExpr *BSE =
460-
dyn_cast<BinarySymExpr>(USE->getOperand())) {
461-
if (USE->getOpcode() == UO_Minus &&
462-
BinaryOperator::isComparisonOp(BSE->getOpcode()))
463-
// The comparison operator yields a boolean value in the Z3
464-
// language and applying the unary minus operator on a boolean
465-
// crashes Z3. However, the unary minus does nothing in this
466-
// context (a number is truthy if and only if its negative is
467-
// truthy), so let's just ignore the unary minus.
468-
// TODO: Replace this with a more general solution.
469-
return OperandExp;
459+
// When the operand is a bool expr, but the operator is an integeral
460+
// operator, casting the bool expr to the integer before creating the
461+
// unary operator.
462+
// E.g. -(5 && a)
463+
if (OperandTy == Ctx.BoolTy && OperandTy != *RetTy &&
464+
(*RetTy)->isIntegerType()) {
465+
OperandExp = fromCast(Solver, OperandExp, (*RetTy),
466+
Ctx.getTypeSize(*RetTy), OperandTy, 1);
467+
OperandTy = (*RetTy);
470468
}
471469

472470
llvm::SMTExprRef UnaryExp =

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,35 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
574574
info.isSigned, isLvalueVolatile,
575575
addr.getAlignment().getAsAlign().value());
576576
}
577+
578+
cir::VecShuffleOp
579+
createVecShuffle(mlir::Location loc, mlir::Value vec1, mlir::Value vec2,
580+
llvm::ArrayRef<mlir::Attribute> maskAttrs) {
581+
auto vecType = mlir::cast<cir::VectorType>(vec1.getType());
582+
auto resultTy = cir::VectorType::get(getContext(), vecType.getElementType(),
583+
maskAttrs.size());
584+
return cir::VecShuffleOp::create(*this, loc, resultTy, vec1, vec2,
585+
getArrayAttr(maskAttrs));
586+
}
587+
588+
cir::VecShuffleOp createVecShuffle(mlir::Location loc, mlir::Value vec1,
589+
mlir::Value vec2,
590+
llvm::ArrayRef<int64_t> mask) {
591+
auto maskAttrs = llvm::to_vector_of<mlir::Attribute>(
592+
llvm::map_range(mask, [&](int32_t idx) {
593+
return cir::IntAttr::get(getSInt32Ty(), idx);
594+
}));
595+
return createVecShuffle(loc, vec1, vec2, maskAttrs);
596+
}
597+
598+
cir::VecShuffleOp createVecShuffle(mlir::Location loc, mlir::Value vec1,
599+
llvm::ArrayRef<int64_t> mask) {
600+
/// Create a unary shuffle. The second vector operand of the IR instruction
601+
/// is poison.
602+
cir::ConstantOp poison =
603+
getConstant(loc, cir::PoisonAttr::get(vec1.getType()));
604+
return createVecShuffle(loc, vec1, poison, mask);
605+
}
577606
};
578607

579608
} // namespace clang::CIRGen

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -669,9 +669,18 @@ RValue CIRGenFunction::emitLoadOfExtVectorElementLValue(LValue lv) {
669669
return RValue::get(cir::VecExtractOp::create(builder, loc, vec, index));
670670
}
671671

672-
cgm.errorNYI(
673-
loc, "emitLoadOfExtVectorElementLValue: Result of expr is vector type");
674-
return {};
672+
// Always use shuffle vector to try to retain the original program structure
673+
SmallVector<int64_t> mask;
674+
for (auto i : llvm::seq<unsigned>(0, exprVecTy->getNumElements()))
675+
mask.push_back(getAccessedFieldNo(i, elts));
676+
677+
cir::VecShuffleOp resultVec = builder.createVecShuffle(loc, vec, mask);
678+
if (lv.getType()->isExtVectorBoolType()) {
679+
cgm.errorNYI(loc, "emitLoadOfExtVectorElementLValue: ExtVectorBoolType");
680+
return {};
681+
}
682+
683+
return RValue::get(resultVec);
675684
}
676685

677686
static cir::FuncOp emitFunctionDeclPointer(CIRGenModule &cgm, GlobalDecl gd) {

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
203203
return emitNullValue(e->getType(), cgf.getLoc(e->getSourceRange()));
204204
}
205205

206+
mlir::Value VisitOffsetOfExpr(OffsetOfExpr *e);
207+
206208
mlir::Value VisitOpaqueValueExpr(OpaqueValueExpr *e) {
207209
if (e->isGLValue())
208210
return emitLoadOfLValue(cgf.getOrCreateOpaqueLValueMapping(e),
@@ -2209,6 +2211,21 @@ mlir::Value ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *e) {
22092211
return maybePromoteBoolResult(boolVal, cgf.convertType(e->getType()));
22102212
}
22112213

2214+
mlir::Value ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *e) {
2215+
// Try folding the offsetof to a constant.
2216+
Expr::EvalResult evalResult;
2217+
if (e->EvaluateAsInt(evalResult, cgf.getContext())) {
2218+
mlir::Type type = cgf.convertType(e->getType());
2219+
llvm::APSInt value = evalResult.Val.getInt();
2220+
return builder.getConstAPInt(cgf.getLoc(e->getExprLoc()), type, value);
2221+
}
2222+
2223+
cgf.getCIRGenModule().errorNYI(
2224+
e->getSourceRange(),
2225+
"ScalarExprEmitter::VisitOffsetOfExpr Can't eval expr as int");
2226+
return {};
2227+
}
2228+
22122229
mlir::Value ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *e) {
22132230
QualType promotionTy = getPromotionType(e->getSubExpr()->getType());
22142231
mlir::Value result = VisitRealImag(e, promotionTy);

clang/test/Analysis/z3-unarysymexpr.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ int z3_crash2(int a) {
4747
return *d; // expected-warning{{Dereference of undefined pointer value}}
4848
return 0;
4949
}
50+
51+
// Refer to issue 165779
52+
void z3_crash3(long a) {
53+
if (~-(5 && a)) {
54+
long *c;
55+
*c; // expected-warning{{Dereference of undefined pointer value (loaded from variable 'c')}}
56+
}
57+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
7+
8+
struct Struct {
9+
int a;
10+
float b;
11+
double c;
12+
bool d;
13+
};
14+
15+
void offset_of_builtin() {
16+
unsigned long a = __builtin_offsetof(Struct, a);
17+
unsigned long b = __builtin_offsetof(Struct, b);
18+
unsigned long c = __builtin_offsetof(Struct, c);
19+
unsigned long d = __builtin_offsetof(Struct, d);
20+
}
21+
22+
// CIR: %[[A_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["a", init]
23+
// CIR: %[[B_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["b", init]
24+
// CIR: %[[C_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["c", init]
25+
// CIR: %[[D_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["d", init]
26+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u64i
27+
// CIR: cir.store {{.*}} %[[CONST_0]], %[[A_ADDR]] : !u64i, !cir.ptr<!u64i>
28+
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !u64i
29+
// CIR: cir.store {{.*}} %[[CONST_4]], %[[B_ADDR]] : !u64i, !cir.ptr<!u64i>
30+
// CIR: %[[CONST_8:.*]] = cir.const #cir.int<8> : !u64i
31+
// CIR: cir.store {{.*}} %[[CONST_8]], %[[C_ADDR]] : !u64i, !cir.ptr<!u64i>
32+
// CIR: %[[CONST_16:.*]] = cir.const #cir.int<16> : !u64i
33+
// CIR: cir.store {{.*}} %[[CONST_16]], %[[D_ADDR]] : !u64i, !cir.ptr<!u64i>
34+
35+
// LLVM: %[[A_ADDR:.*]] = alloca i64, i64 1, align 8
36+
// LLVM: %[[B_ADDR:.*]] = alloca i64, i64 1, align 8
37+
// LLVM: %[[C_ADDR:.*]] = alloca i64, i64 1, align 8
38+
// LLVM: %[[D_ADDR:.*]] = alloca i64, i64 1, align 8
39+
// LLVM: store i64 0, ptr %[[A_ADDR]], align 8
40+
// LLVM: store i64 4, ptr %[[B_ADDR]], align 8
41+
// LLVM: store i64 8, ptr %[[C_ADDR]], align 8
42+
// LLVM: store i64 16, ptr %[[D_ADDR]], align 8
43+
44+
// OGCG: %[[A_ADDR:.*]] = alloca i64, align 8
45+
// OGCG: %[[B_ADDR:.*]] = alloca i64, align 8
46+
// OGCG: %[[C_ADDR:.*]] = alloca i64, align 8
47+
// OGCG: %[[D_ADDR:.*]] = alloca i64, align 8
48+
// OGCG: store i64 0, ptr %[[A_ADDR]], align 8
49+
// OGCG: store i64 4, ptr %[[B_ADDR]], align 8
50+
// OGCG: store i64 8, ptr %[[C_ADDR]], align 8
51+
// OGCG: store i64 16, ptr %[[D_ADDR]], align 8
52+
53+
struct StructWithArray {
54+
Struct array[4][4];
55+
};
56+
57+
void offset_of_builtin_from_array_element() {
58+
unsigned long a = __builtin_offsetof(StructWithArray, array[0][0].a);
59+
unsigned long b = __builtin_offsetof(StructWithArray, array[1][1].b);
60+
unsigned long c = __builtin_offsetof(StructWithArray, array[2][2].c);
61+
unsigned long d = __builtin_offsetof(StructWithArray, array[3][3].d);
62+
}
63+
64+
// CIR: %[[A_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["a", init]
65+
// CIR: %[[B_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["b", init]
66+
// CIR: %[[C_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["c", init]
67+
// CIR: %[[D_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["d", init]
68+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u64i
69+
// CIR: cir.store {{.*}} %[[CONST_0]], %[[A_ADDR]] : !u64i, !cir.ptr<!u64i>
70+
// CIR: %[[CONST_124:.*]] = cir.const #cir.int<124> : !u64i
71+
// CIR: cir.store {{.*}} %[[CONST_124]], %[[B_ADDR]] : !u64i, !cir.ptr<!u64i>
72+
// CIR: %[[CONST_248:.*]] = cir.const #cir.int<248> : !u64i
73+
// CIR: cir.store {{.*}} %[[CONST_248]], %[[C_ADDR]] : !u64i, !cir.ptr<!u64i>
74+
// CIR: %[[CONST_376:.*]] = cir.const #cir.int<376> : !u64i
75+
// CIR: cir.store {{.*}} %[[CONST_376]], %[[D_ADDR]] : !u64i, !cir.ptr<!u64i>
76+
77+
// LLVM: %[[A_ADDR:.*]] = alloca i64, i64 1, align 8
78+
// LLVM: %[[B_ADDR:.*]] = alloca i64, i64 1, align 8
79+
// LLVM: %[[C_ADDR:.*]] = alloca i64, i64 1, align 8
80+
// LLVM: %[[D_ADDR:.*]] = alloca i64, i64 1, align 8
81+
// LLVM: store i64 0, ptr %[[A_ADDR]], align 8
82+
// LLVM: store i64 124, ptr %[[B_ADDR]], align 8
83+
// LLVM: store i64 248, ptr %[[C_ADDR]], align 8
84+
// LLVM: store i64 376, ptr %[[D_ADDR]], align 8
85+
86+
// OGCG: %[[A_ADDR:.*]] = alloca i64, align 8
87+
// OGCG: %[[B_ADDR:.*]] = alloca i64, align 8
88+
// OGCG: %[[C_ADDR:.*]] = alloca i64, align 8
89+
// OGCG: %[[D_ADDR:.*]] = alloca i64, align 8
90+
// OGCG: store i64 0, ptr %[[A_ADDR]], align 8
91+
// OGCG: store i64 124, ptr %[[B_ADDR]], align 8
92+
// OGCG: store i64 248, ptr %[[C_ADDR]], align 8
93+
// OGCG: store i64 376, ptr %[[D_ADDR]], align 8

clang/test/CIR/CodeGen/vector-ext-element.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
66
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
77

8+
typedef int vi2 __attribute__((ext_vector_type(2)));
89
typedef int vi4 __attribute__((ext_vector_type(4)));
910

1011
void element_expr_from_gl() {
@@ -44,3 +45,41 @@ void element_expr_from_gl() {
4445
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[A_ADDR]], align 16
4546
// OGCG: %[[ELEM_1:.*]] = extractelement <4 x i32> %[[TMP_A]], i64 1
4647
// OGCG: store i32 %[[ELEM_1]], ptr %[[Y_ADDR]], align 4
48+
49+
void element_expr_from_gl_with_vec_result() {
50+
vi4 a;
51+
vi2 b = a.xy;
52+
vi4 c = a.wzyx;
53+
}
54+
55+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a"]
56+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.vector<2 x !s32i>, !cir.ptr<!cir.vector<2 x !s32i>>, ["b", init]
57+
// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["c", init]
58+
// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
59+
// CIR: %[[POISON:.*]] = cir.const #cir.poison : !cir.vector<4 x !s32i>
60+
// CIR: %[[B_VALUE:.*]] = cir.vec.shuffle(%[[TMP_A]], %[[POISON]] : !cir.vector<4 x !s32i>) [#cir.int<0> : !s32i, #cir.int<1> : !s32i] : !cir.vector<2 x !s32i>
61+
// CIR: cir.store {{.*}} %[[B_VALUE]], %[[B_ADDR]] : !cir.vector<2 x !s32i>, !cir.ptr<!cir.vector<2 x !s32i>>
62+
// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
63+
// CIR: %[[POISON:.*]] = cir.const #cir.poison : !cir.vector<4 x !s32i>
64+
// CIR: %[[C_VALUE:.*]] = cir.vec.shuffle(%[[TMP_A]], %[[POISON]] : !cir.vector<4 x !s32i>) [#cir.int<3> : !s32i, #cir.int<2> : !s32i, #cir.int<1> : !s32i, #cir.int<0> : !s32i] : !cir.vector<4 x !s32i>
65+
// CIR: cir.store {{.*}} %[[C_VALUE]], %[[C_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
66+
67+
// LLVM: %[[A_ADDR:.*]] = alloca <4 x i32>, i64 1, align 16
68+
// LLVM: %[[B_ADDR:.*]] = alloca <2 x i32>, i64 1, align 8
69+
// LLVM: %[[C_ADDR:.*]] = alloca <4 x i32>, i64 1, align 16
70+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[A_ADDR]], align 16
71+
// LLVM: %[[B_VALUE:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> poison, <2 x i32> <i32 0, i32 1>
72+
// LLVM: store <2 x i32> %[[B_VALUE]], ptr %[[B_ADDR]], align 8
73+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[A_ADDR]], align 16
74+
// LLVM: %[[C_VALUE:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
75+
// LLVM: store <4 x i32> %[[C_VALUE]], ptr %[[C_ADDR]], align 16
76+
77+
// OGCG: %[[A_ADDR:.*]] = alloca <4 x i32>, align 16
78+
// OGCG: %[[B_ADDR:.*]] = alloca <2 x i32>, align 8
79+
// OGCG: %[[C_ADDR:.*]] = alloca <4 x i32>, align 16
80+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[A_ADDR]], align 16
81+
// OGCG: %[[B_VALUE:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> poison, <2 x i32> <i32 0, i32 1>
82+
// OGCG: store <2 x i32> %[[B_VALUE]], ptr %[[B_ADDR]], align 8
83+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[A_ADDR]], align 16
84+
// OGCG: %[[C_VALUE:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
85+
// OGCG: store <4 x i32> %[[C_VALUE]], ptr %[[C_ADDR]], align 16

libcxx/include/limits

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ template<> class numeric_limits<cv long double>;
107107
#else
108108
# include <__config>
109109
# include <__type_traits/is_arithmetic.h>
110+
# include <__type_traits/is_same.h>
110111
# include <__type_traits/is_signed.h>
111112

112113
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -220,7 +221,7 @@ protected:
220221
static _LIBCPP_CONSTEXPR const bool is_modulo = !std::is_signed<_Tp>::value;
221222

222223
# if defined(__i386__) || defined(__x86_64__) || defined(__wasm__)
223-
static _LIBCPP_CONSTEXPR const bool traps = true;
224+
static _LIBCPP_CONSTEXPR const bool traps = is_same<decltype(+_Tp(0)), _Tp>::value;
224225
# else
225226
static _LIBCPP_CONSTEXPR const bool traps = false;
226227
# endif

libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// traps
1212

13+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
14+
1315
#include <limits>
1416

1517
#include "test_macros.h"
@@ -33,17 +35,17 @@ test()
3335
int main(int, char**)
3436
{
3537
test<bool, false>();
36-
test<char, integral_types_trap>();
37-
test<signed char, integral_types_trap>();
38-
test<unsigned char, integral_types_trap>();
39-
test<wchar_t, integral_types_trap>();
38+
test<char, false>();
39+
test<signed char, false>();
40+
test<unsigned char, false>();
41+
test<wchar_t, false>();
4042
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
41-
test<char8_t, integral_types_trap>();
43+
test<char8_t, false>();
4244
#endif
43-
test<char16_t, integral_types_trap>();
44-
test<char32_t, integral_types_trap>();
45-
test<short, integral_types_trap>();
46-
test<unsigned short, integral_types_trap>();
45+
test<char16_t, false>();
46+
test<char32_t, false>();
47+
test<short, false>();
48+
test<unsigned short, false>();
4749
test<int, integral_types_trap>();
4850
test<unsigned int, integral_types_trap>();
4951
test<long, integral_types_trap>();

llvm/include/llvm/MC/MCAsmBackend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ class LLVM_ABI MCAsmBackend {
200200

201201
// Return true if fragment offsets have been adjusted and an extra layout
202202
// iteration is needed.
203-
virtual bool finishLayout(const MCAssembler &Asm) const { return false; }
203+
virtual bool finishLayout() const { return false; }
204204

205205
/// Generate the compact unwind encoding for the CFI instructions.
206206
virtual uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,

0 commit comments

Comments
 (0)