[clang] [OpenMP] Fix OpenMP reduction segfault with non-copyable types and user initializers. (PR #219265)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 28 05:49:47 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Zahira Ammarguellat (zahiraam)
<details>
<summary>Changes</summary>
OpenMP custom reductions with user-defined initializers segfault when the reduction variable type is non-copyable and has non-trivial members (e.g., std::string). `Clang` was emitting only the user initializer function call, leaving non-trivial
members uninitialized with garbage values, causing segfaults when those members are accessed or assigned.
See https://godbolt.org/z/bboqKbhsT
This patch fixes the issue.
---
Patch is 46.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/219265.diff
3 Files Affected:
- (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+41-4)
- (modified) clang/test/OpenMP/for_reduction_codegen_UDR.cpp (+93-91)
- (added) clang/test/OpenMP/reduction_non_copyable_with_initializer.cpp (+65)
``````````diff
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 9f8822a37bf71..9dfbc8adcc12b 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1125,9 +1125,10 @@ emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty,
In, CGF.EmitLoadOfPointerLValue(AddrIn, PtrTy->castAs<PointerType>())
.getAddress());
Address AddrOut = CGF.GetAddrOfLocalVar(OmpOutParm);
- Scope.addPrivate(
- Out, CGF.EmitLoadOfPointerLValue(AddrOut, PtrTy->castAs<PointerType>())
- .getAddress());
+ Address OutDerefAddr =
+ CGF.EmitLoadOfPointerLValue(AddrOut, PtrTy->castAs<PointerType>())
+ .getAddress();
+ Scope.addPrivate(Out, OutDerefAddr);
(void)Scope.Privatize();
if (!IsCombiner && Out->hasInit() &&
!CGF.isTrivialInitializer(Out->getInit())) {
@@ -1135,8 +1136,44 @@ emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty,
Out->getType().getQualifiers(),
/*IsInitializer=*/true);
}
- if (CombinerInitializer)
+ if (CombinerInitializer) {
+ // For non-trivial types with user initializers, we must emit default
+ // construction first to properly initialize members (e.g., std::string)
+ // before the user initializer assigns to them. This matches GCC behavior.
+ if (!IsCombiner && Ty.isDestructedType() != QualType::DK_none) {
+ if (const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl()) {
+ for (const CXXConstructorDecl *Ctor : RD->ctors()) {
+ if (Ctor->isDefaultConstructor()) {
+ // Synthesize CXXConstructExpr for default construction.
+ // Collect default arguments for parameters with defaults.
+ ASTContext &Ctx = CGM.getContext();
+ SmallVector<Expr *, 4> Args;
+ for (unsigned I = 0; I < Ctor->getNumParams(); ++I)
+ if (const ParmVarDecl *Param = Ctor->getParamDecl(I);
+ Param->hasDefaultArg())
+ Args.push_back(const_cast<Expr *>(Param->getDefaultArg()));
+
+ CXXConstructExpr *CtorExpr = CXXConstructExpr::Create(
+ Ctx, Ty, Out->getLocation(),
+ const_cast<CXXConstructorDecl *>(Ctor), /*Elidable=*/false,
+ /*Args=*/Args,
+ /*HadMultipleCandidates=*/false, /*ListInit=*/false,
+ /*StdInitListInit=*/false, /*ZeroInit=*/false,
+ CXXConstructionKind::Complete, SourceRange());
+
+ // Emit the constructor call
+ AggValueSlot Slot = AggValueSlot::forAddr(
+ OutDerefAddr, Ty.getQualifiers(), AggValueSlot::IsDestructed,
+ AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased,
+ AggValueSlot::DoesNotOverlap);
+ CGF.EmitCXXConstructExpr(CtorExpr, Slot);
+ break;
+ }
+ }
+ }
+ }
CGF.EmitIgnoredExpr(CombinerInitializer);
+ }
Scope.ForceCleanup();
CGF.FinishFunction();
return Fn;
diff --git a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp
index 0ac82685803db..a33d93c7ebdc4 100644
--- a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp
+++ b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp
@@ -508,29 +508,29 @@ int main() {
// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
-// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8, !nonnull [[META3:![0-9]+]], !align [[META4:![0-9]+]]
+// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]]
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IV]], align 4
// CHECK1-NEXT: call void @.omp_initializer.(ptr noundef [[S1]], ptr noundef [[TMP0]])
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
-// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]]
+// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP4:![0-9]+]]
// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 10
// CHECK1-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
-// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP5]]
+// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP4]]
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP2]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP5]]
+// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP4]]
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
-// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP5]]
+// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP4]]
// CHECK1-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP3]], 1
-// CHECK1-NEXT: store i32 [[ADD2]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP5]]
-// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
+// CHECK1-NEXT: store i32 [[ADD2]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP4]]
+// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: store i32 10, ptr [[I]], align 4
// CHECK1-NEXT: call void @.omp_combiner.(ptr noundef [[TMP0]], ptr noundef [[S1]])
@@ -654,7 +654,7 @@ int main() {
// CHECK1-NEXT: br i1 [[ARRAYCTOR_DONE8]], label [[ARRAYCTOR_CONT9:%.*]], label [[ARRAYCTOR_LOOP5]]
// CHECK1: arrayctor.cont9:
// CHECK1-NEXT: store ptr [[S_ARR]], ptr [[VAR3]], align 8
-// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 6, ptr @main.omp_outlined, ptr [[T_VAR]], ptr [[TMP0]], ptr [[VAR1]], ptr [[T_VAR1]], ptr [[VEC]], ptr [[S_ARR]])
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], ptr [[VEC]], i64 0, i64 1
// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
@@ -668,9 +668,9 @@ int main() {
// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 4, ptr @main.omp_outlined.11, i64 10, i64 [[TMP2]], ptr [[VLA]], ptr [[ARRS]])
// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @main.omp_outlined.12, ptr [[VAR2]])
// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @main.omp_outlined.13, ptr [[VVAR2]])
-// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[VAR3]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[VAR3]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @main.omp_outlined.14, ptr [[TMP5]])
-// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[VAR3]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[VAR3]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @main.omp_outlined.15, ptr [[TMP6]])
// CHECK1-NEXT: [[CALL10:%.*]] = call noundef i32 @_Z5tmainIiLi42EET_v()
// CHECK1-NEXT: store i32 [[CALL10]], ptr [[RETVAL]], align 4
@@ -769,21 +769,21 @@ int main() {
// CHECK1-NEXT: store ptr [[T_VAR1]], ptr [[T_VAR1_ADDR]], align 8
// CHECK1-NEXT: store ptr [[VEC]], ptr [[VEC_ADDR]], align 8
// CHECK1-NEXT: store ptr [[S_ARR]], ptr [[S_ARR_ADDR]], align 8
-// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[T_VAR_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
-// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
-// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAR1_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
-// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[T_VAR1_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
-// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[VEC_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
-// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[S_ARR_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[T_VAR_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAR1_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[T_VAR1_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[VEC_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[S_ARR_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8
-// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: store ptr [[TMP6]], ptr [[_TMP1]], align 8
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: call void @.omp_initializer..2(ptr noundef [[T_VAR3]], ptr noundef [[TMP0]])
-// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[VAR4]], i64 4
// CHECK1-NEXT: [[ADD_PTR5:%.*]] = getelementptr inbounds i8, ptr [[TMP7]], i64 4
// CHECK1-NEXT: call void @.omp_initializer..4(ptr noundef [[ADD_PTR]], ptr noundef [[ADD_PTR5]])
@@ -826,7 +826,7 @@ int main() {
// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP18]] to i64
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], ptr [[TMP4]], i64 0, i64 [[IDXPROM]]
// CHECK1-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4
-// CHECK1-NEXT: [[TMP19:%.*]] = load ptr, ptr [[_TMP6]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP19:%.*]] = load ptr, ptr [[_TMP6]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[I]], align 4
// CHECK1-NEXT: [[IDXPROM10:%.*]] = sext i32 [[TMP20]] to i64
// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [4 x [[STRUCT_S_0]]], ptr [[TMP5]], i64 0, i64 [[IDXPROM10]]
@@ -970,6 +970,7 @@ int main() {
// CHECK1-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR]], align 8
+// CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(12) [[TMP3]])
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 4
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 4
// CHECK1-NEXT: call void @_Z5init1R6BaseS1RKS_(ptr noundef nonnull align 4 dereferenceable(4) [[ADD_PTR]], ptr noundef nonnull align 4 dereferenceable(4) [[ADD_PTR2]])
@@ -1065,9 +1066,9 @@ int main() {
// CHECK1-NEXT: store ptr [[ARRS]], ptr [[ARRS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[VLA_ADDR2]], align 8
-// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
-// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VEC_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
-// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRS_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VEC_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRS_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
@@ -1403,8 +1404,8 @@ int main() {
// CHECK1-NEXT: store ptr [[ARRS]], ptr [[ARRS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[VLA_ADDR]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[VLA_ADDR2]], align 8
-// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
-// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[ARRS_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[ARRS_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
@@ -1663,7 +1664,7 @@ int main() {
// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[VAR2]], ptr [[VAR2_ADDR]], align 8
-// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR2_ADDR]], align 8, !nonnull [[META3]], !align [[META11:![0-9]+]]
+// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR2_ADDR]], align 8, !nonnull [[META2]], !align [[META10:![0-9]+]]
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
@@ -1872,7 +1873,7 @@ int main() {
// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[VVAR2]], ptr [[VVAR2_ADDR]], align 8
-// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VVAR2_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VVAR2_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
@@ -2057,17 +2058,17 @@ int main() {
// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[VAR3]], ptr [[VAR3_ADDR]], align 8
-// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR3_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR3_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: store ptr [[TMP0]], ptr [[TMP]], align 8
-// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: store ptr [[TMP1]], ptr [[_TMP1]], align 8
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4 x [[STRUCT_S_0]]], ptr [[TMP2]], i64 0, i64 1
-// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [4 x [[STRUCT_S_0]]], ptr [[TMP3]], i64 0, i64 2
// CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x [[STRUCT_S_0]]], ptr [[VAR34]], i32 0, i32 0
// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_S_0]], ptr [[ARRAY_BEGIN]], i64 2
@@ -2084,7 +2085,7 @@ int main() {
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq ptr [[OMP_ARRAYCPY_DEST_ELEMENT6]], [[TMP4]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYINIT_DONE]], label [[OMP_ARRAYINIT_BODY]]
// CHECK1: omp.arrayinit.done:
-// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: [[TMP6:%.*]] = ptrtoaddr ptr [[TMP5]] to i64
// CHECK1-NEXT: [[TMP7:%.*]] = ptrtoaddr ptr [[ARRAYIDX]] to i64
// CHECK1-NEXT: [[TMP8:%.*]] = sub i64 [[TMP6]], [[TMP7]]
@@ -2248,15 +2249,15 @@ int main() {
// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store ptr [[VAR3]], ptr [[VAR3_ADDR]], align 8
-// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR3_ADDR]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR3_ADDR]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: store ptr [[TMP0]], ptr [[TMP]], align 8
-// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: store ptr [[TMP1]], ptr [[_TMP1]], align 8
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[_TMP1]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
// CHECK1-NEXT: [[DOTVAR3__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP4]], i64 48, ptr inttoptr (i64 6 to ptr))
@@ -2435,11 +2436,11 @@ int main() {
// CHECK1-NEXT: [[ARRAYCTOR_DONE:%.*]] = icmp eq ptr [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]]
// CHECK1-NEXT: br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]]
// CHECK1: arrayctor.cont:
-// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !nonnull [[META3]], !align [[META4]]
+// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !nonnull [[META2]], !align [[META3]]
// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 6, p...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/219265
More information about the cfe-commits
mailing list