Skip to content

Commit 59557e5

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:79382eb97adff71dbc9d4969431dd4a0967ee7ad into amd-gfx:685560350718
Local branch amd-gfx 6855603 Manual merge remote-tracking branch llvm-org/main into amd-gfx Remote branch main 79382eb [clang][bytecode] Remove superfluous check from fixed-point div (llvm#110478)
2 parents 6855603 + 79382eb commit 59557e5

28 files changed

+2863
-70
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,19 +1542,30 @@ bool Compiler<Emitter>::VisitFixedPointBinOp(const BinaryOperator *E) {
15421542
return true;
15431543
};
15441544

1545+
auto MaybeCastToBool = [&](bool Result) {
1546+
if (!Result)
1547+
return false;
1548+
PrimType T = classifyPrim(E);
1549+
if (DiscardResult)
1550+
return this->emitPop(T, E);
1551+
if (T != PT_Bool)
1552+
return this->emitCast(PT_Bool, T, E);
1553+
return true;
1554+
};
1555+
15451556
switch (E->getOpcode()) {
15461557
case BO_EQ:
1547-
return this->emitEQFixedPoint(E);
1558+
return MaybeCastToBool(this->emitEQFixedPoint(E));
15481559
case BO_NE:
1549-
return this->emitNEFixedPoint(E);
1560+
return MaybeCastToBool(this->emitNEFixedPoint(E));
15501561
case BO_LT:
1551-
return this->emitLTFixedPoint(E);
1562+
return MaybeCastToBool(this->emitLTFixedPoint(E));
15521563
case BO_LE:
1553-
return this->emitLEFixedPoint(E);
1564+
return MaybeCastToBool(this->emitLEFixedPoint(E));
15541565
case BO_GT:
1555-
return this->emitGTFixedPoint(E);
1566+
return MaybeCastToBool(this->emitGTFixedPoint(E));
15561567
case BO_GE:
1557-
return this->emitGEFixedPoint(E);
1568+
return MaybeCastToBool(this->emitGEFixedPoint(E));
15581569
case BO_Add:
15591570
return ConvertResult(this->emitAddFixedPoint(E));
15601571
case BO_Sub:

clang/lib/AST/ByteCode/Interp.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,16 @@ bool CheckDivRem(InterpState &S, CodePtr OpPC, const T &LHS, const T &RHS) {
235235
return false;
236236
}
237237

238-
if (LHS.isSigned() && LHS.isMin() && RHS.isNegative() && RHS.isMinusOne()) {
239-
APSInt LHSInt = LHS.toAPSInt();
240-
SmallString<32> Trunc;
241-
(-LHSInt.extend(LHSInt.getBitWidth() + 1)).toString(Trunc, 10);
242-
const SourceInfo &Loc = S.Current->getSource(OpPC);
243-
const Expr *E = S.Current->getExpr(OpPC);
244-
S.CCEDiag(Loc, diag::note_constexpr_overflow) << Trunc << E->getType();
245-
return false;
238+
if constexpr (!std::is_same_v<T, FixedPoint>) {
239+
if (LHS.isSigned() && LHS.isMin() && RHS.isNegative() && RHS.isMinusOne()) {
240+
APSInt LHSInt = LHS.toAPSInt();
241+
SmallString<32> Trunc;
242+
(-LHSInt.extend(LHSInt.getBitWidth() + 1)).toString(Trunc, 10);
243+
const SourceInfo &Loc = S.Current->getSource(OpPC);
244+
const Expr *E = S.Current->getExpr(OpPC);
245+
S.CCEDiag(Loc, diag::note_constexpr_overflow) << Trunc << E->getType();
246+
return false;
247+
}
246248
}
247249
return true;
248250
}

clang/test/Frontend/fixed_point_comparisons.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNPADDED
22
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,PADDED
33

4+
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,UNPADDED
5+
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -emit-llvm %s -o - -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,PADDED
6+
47
// Fixed point against other fixed point
58
_Bool b_eq_true = 2.5hk == 2.5uhk; // CHECK-DAG: @b_eq_true = {{.*}}global i8 1, align 1
69
_Bool b_eq_false = 2.5hk == 2.4uhk; // CHECK-DAG: @b_eq_false = {{.*}}global i8 0, align 1

clang/test/Frontend/fixed_point_div_const.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
22
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
33

4+
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,SIGNED
5+
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -emit-llvm %s -o - -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,UNSIGNED
6+
47
// Division between different fixed point types
58
short _Accum sa_const = 1.0hk / 2.0hk;
69
// CHECK-DAG: @sa_const = {{.*}}global i16 64, align 2

flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp

Lines changed: 101 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
#include "DebugTypeGenerator.h"
1616
#include "flang/Optimizer/CodeGen/DescriptorModel.h"
17-
#include "flang/Optimizer/CodeGen/TypeConverter.h"
1817
#include "flang/Optimizer/Support/InternalNames.h"
1918
#include "mlir/Pass/Pass.h"
2019
#include "llvm/ADT/ScopeExit.h"
@@ -48,7 +47,7 @@ DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m,
4847
mlir::SymbolTable *symbolTable_,
4948
const mlir::DataLayout &dl)
5049
: module(m), symbolTable(symbolTable_), dataLayout{&dl},
51-
kindMapping(getKindMapping(m)) {
50+
kindMapping(getKindMapping(m)), llvmTypeConverter(m, false, false, dl) {
5251
LLVM_DEBUG(llvm::dbgs() << "DITypeAttr generator\n");
5352

5453
mlir::MLIRContext *context = module.getContext();
@@ -160,29 +159,110 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
160159
dataLocation, /*rank=*/nullptr, allocated, associated);
161160
}
162161

162+
// If the type is a pointer or array type then gets its underlying type.
163+
static mlir::LLVM::DITypeAttr getUnderlyingType(mlir::LLVM::DITypeAttr Ty) {
164+
if (auto ptrTy =
165+
mlir::dyn_cast_if_present<mlir::LLVM::DIDerivedTypeAttr>(Ty)) {
166+
if (ptrTy.getTag() == llvm::dwarf::DW_TAG_pointer_type)
167+
Ty = getUnderlyingType(ptrTy.getBaseType());
168+
}
169+
if (auto comTy =
170+
mlir::dyn_cast_if_present<mlir::LLVM::DICompositeTypeAttr>(Ty)) {
171+
if (comTy.getTag() == llvm::dwarf::DW_TAG_array_type)
172+
Ty = getUnderlyingType(comTy.getBaseType());
173+
}
174+
return Ty;
175+
}
176+
177+
// Currently, the handling of recursive debug type in mlir has some limitations.
178+
// Those limitations were discussed at the end of the thread for following PR.
179+
// https://github.com/llvm/llvm-project/pull/106571
180+
//
181+
// Problem could be explained with the following example code:
182+
// type t2
183+
// type(t1), pointer :: p1
184+
// end type
185+
// type t1
186+
// type(t2), pointer :: p2
187+
// end type
188+
// In the description below, type_self means a temporary type that is generated
189+
// as a place holder while the members of that type are being processed.
190+
//
191+
// If we process t1 first then we will have the following structure after it has
192+
// been processed.
193+
// t1 -> t2 -> t1_self
194+
// This is because when we started processing t2, we did not have the complete
195+
// t1 but its place holder t1_self.
196+
// Now if some entity requires t2, we will already have that in cache and will
197+
// return it. But this t2 refers to t1_self and not to t1. In mlir handling,
198+
// only those types are allowed to have _self reference which are wrapped by
199+
// entity whose reference it is. So t1 -> t2 -> t1_self is ok because the
200+
// t1_self reference can be resolved by the outer t1. But standalone t2 is not
201+
// because there will be no way to resolve it. Until this is fixed in mlir, we
202+
// avoid caching such types. Please see DebugTranslation::translateRecursive for
203+
// details on how mlir handles recursive types.
204+
static bool canCacheThisType(mlir::LLVM::DICompositeTypeAttr comTy) {
205+
for (auto el : comTy.getElements()) {
206+
if (auto mem =
207+
mlir::dyn_cast_if_present<mlir::LLVM::DIDerivedTypeAttr>(el)) {
208+
mlir::LLVM::DITypeAttr memTy = getUnderlyingType(mem.getBaseType());
209+
if (auto baseTy =
210+
mlir::dyn_cast_if_present<mlir::LLVM::DICompositeTypeAttr>(
211+
memTy)) {
212+
// We will not cache a type if one of its member meets the following
213+
// conditions:
214+
// 1. It is a structure type
215+
// 2. It is a place holder type (getIsRecSelf() is true)
216+
// 3. It is not a self reference. It is ok to have t1_self in t1.
217+
if (baseTy.getTag() == llvm::dwarf::DW_TAG_structure_type &&
218+
baseTy.getIsRecSelf() && (comTy.getRecId() != baseTy.getRecId()))
219+
return false;
220+
}
221+
}
222+
}
223+
return true;
224+
}
225+
163226
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
164227
fir::RecordType Ty, mlir::LLVM::DIFileAttr fileAttr,
165228
mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
229+
// Check if this type has already been converted.
230+
auto iter = typeCache.find(Ty);
231+
if (iter != typeCache.end())
232+
return iter->second;
233+
234+
llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
166235
mlir::MLIRContext *context = module.getContext();
236+
auto recId = mlir::DistinctAttr::create(mlir::UnitAttr::get(context));
237+
// Generate a place holder TypeAttr which will be used if a member
238+
// references the parent type.
239+
auto comAttr = mlir::LLVM::DICompositeTypeAttr::get(
240+
context, recId, /*isRecSelf=*/true, llvm::dwarf::DW_TAG_structure_type,
241+
mlir::StringAttr::get(context, ""), fileAttr, /*line=*/0, scope,
242+
/*baseType=*/nullptr, mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0,
243+
/*alignInBits=*/0, elements, /*dataLocation=*/nullptr, /*rank=*/nullptr,
244+
/*allocated=*/nullptr, /*associated=*/nullptr);
245+
typeCache[Ty] = comAttr;
246+
167247
auto result = fir::NameUniquer::deconstruct(Ty.getName());
168248
if (result.first != fir::NameUniquer::NameKind::DERIVED_TYPE)
169249
return genPlaceholderType(context);
170250

171251
fir::TypeInfoOp tiOp = symbolTable->lookup<fir::TypeInfoOp>(Ty.getName());
172252
unsigned line = (tiOp) ? getLineFromLoc(tiOp.getLoc()) : 1;
173253

174-
llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
175254
std::uint64_t offset = 0;
176255
for (auto [fieldName, fieldTy] : Ty.getTypeList()) {
177-
auto result = fir::getTypeSizeAndAlignment(module.getLoc(), fieldTy,
178-
*dataLayout, kindMapping);
179-
// If we get a type whose size we can't determine, we will break the loop
180-
// and generate the derived type with whatever components we have
181-
// assembled thus far.
182-
if (!result)
183-
break;
184-
auto [byteSize, byteAlign] = *result;
256+
mlir::Type llvmTy;
257+
if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(fieldTy))
258+
llvmTy =
259+
llvmTypeConverter.convertBoxTypeAsStruct(boxTy, getBoxRank(boxTy));
260+
else
261+
llvmTy = llvmTypeConverter.convertType(fieldTy);
262+
185263
// FIXME: Handle non defaults array bound in derived types
264+
uint64_t byteSize = dataLayout->getTypeSize(llvmTy);
265+
unsigned short byteAlign = dataLayout->getTypeABIAlignment(llvmTy);
186266
mlir::LLVM::DITypeAttr elemTy =
187267
convertType(fieldTy, fileAttr, scope, /*declOp=*/nullptr);
188268
offset = llvm::alignTo(offset, byteAlign);
@@ -195,12 +275,20 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
195275
offset += llvm::alignTo(byteSize, byteAlign);
196276
}
197277

198-
return mlir::LLVM::DICompositeTypeAttr::get(
199-
context, llvm::dwarf::DW_TAG_structure_type,
278+
auto finalAttr = mlir::LLVM::DICompositeTypeAttr::get(
279+
context, recId, /*isRecSelf=*/false, llvm::dwarf::DW_TAG_structure_type,
200280
mlir::StringAttr::get(context, result.second.name), fileAttr, line, scope,
201281
/*baseType=*/nullptr, mlir::LLVM::DIFlags::Zero, offset * 8,
202282
/*alignInBits=*/0, elements, /*dataLocation=*/nullptr, /*rank=*/nullptr,
203283
/*allocated=*/nullptr, /*associated=*/nullptr);
284+
if (canCacheThisType(finalAttr)) {
285+
typeCache[Ty] = finalAttr;
286+
} else {
287+
auto iter = typeCache.find(Ty);
288+
if (iter != typeCache.end())
289+
typeCache.erase(iter);
290+
}
291+
return finalAttr;
204292
}
205293

206294
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(

flang/lib/Optimizer/Transforms/DebugTypeGenerator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define FORTRAN_OPTIMIZER_TRANSFORMS_DEBUGTYPEGENERATOR_H
1515

1616
#include "flang/Optimizer/CodeGen/CGOps.h"
17+
#include "flang/Optimizer/CodeGen/TypeConverter.h"
1718
#include "flang/Optimizer/Dialect/FIRType.h"
1819
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
1920
#include "flang/Optimizer/Dialect/Support/KindMapping.h"
@@ -68,10 +69,12 @@ class DebugTypeGenerator {
6869
mlir::SymbolTable *symbolTable;
6970
const mlir::DataLayout *dataLayout;
7071
KindMapping kindMapping;
72+
fir::LLVMTypeConverter llvmTypeConverter;
7173
std::uint64_t dimsSize;
7274
std::uint64_t dimsOffset;
7375
std::uint64_t ptrSize;
7476
std::uint64_t lenOffset;
77+
llvm::DenseMap<mlir::Type, mlir::LLVM::DITypeAttr> typeCache;
7578
};
7679

7780
} // namespace fir
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
2+
3+
! mainly test that this program does not cause an assertion failure
4+
module m
5+
type t2
6+
type(t1), pointer :: p1
7+
end type
8+
type t1
9+
type(t2), pointer :: p2
10+
integer abc
11+
end type
12+
type(t1) :: tee1
13+
end module
14+
15+
program test
16+
use m
17+
type(t2) :: lc2
18+
print *, lc2%p1%abc
19+
end program test
20+
21+
! CHECK-DAG: DICompositeType(tag: DW_TAG_structure_type, name: "t1"{{.*}})
22+
! CHECK-DAG: DICompositeType(tag: DW_TAG_structure_type, name: "t2"{{.*}})

flang/test/Integration/debug-cyclic-derived-type.f90

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,11 @@ module m
1111
type(t2) :: v3
1212
end module
1313

14-
! CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "t1"{{.*}})
15-
! CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "t2"{{.*}})
14+
! CHECK-DAG: ![[T1:[0-9]+]] = {{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "t1"{{.*}}elements: ![[T1_ELEMS:[0-9]+]])
15+
! CHECK-DAG: ![[T1_ELEMS]] = !{![[T1_ELEM1:[0-9]+]]}
16+
! CHECK-DAG: ![[T1_ELEM1]] = !DIDerivedType(tag: DW_TAG_member, name: "p", baseType: ![[T2P:[0-9]+]]{{.*}})
17+
! CHECK-DAG: ![[T2P]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[T2:[0-9]+]]{{.*}})
18+
19+
! CHECK-DAG: ![[T2]] = {{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "t2"{{.*}}elements: ![[T2_ELEMS:[0-9]+]])
20+
! CHECK-DAG: ![[T2_ELEMS]] = !{![[T2_ELEM1:[0-9]+]]}
21+
! CHECK-DAG: ![[T2_ELEM1]] = !DIDerivedType(tag: DW_TAG_member, name: "v1", baseType: ![[T1]]{{.*}})

0 commit comments

Comments
 (0)