[clang] f90abac - [OpenMP] Use compound operators for reduction combiner if available.

Mike Rice via cfe-commits cfe-commits at lists.llvm.org
Tue May 11 11:41:54 PDT 2021


Author: Mike Rice
Date: 2021-05-11T11:39:12-07:00
New Revision: f90abac6caab3b44e6a000de8cb72d204e74eb76

URL: https://github.com/llvm/llvm-project/commit/f90abac6caab3b44e6a000de8cb72d204e74eb76
DIFF: https://github.com/llvm/llvm-project/commit/f90abac6caab3b44e6a000de8cb72d204e74eb76.diff

LOG: [OpenMP] Use compound operators for reduction combiner if available.

The OpenMP spec seems to require the compound operators be used for
+, *, &, |, and ^ reduction.  So use these if a class has those operators.
If not try the simple operators as we did previously to limit the impact
to existing code.

Fixes: https://bugs.llvm.org/show_bug.cgi?id=48584

Differential Revision: https://reviews.llvm.org/D101941

Added: 
    clang/test/OpenMP/reduction_compound_op.cpp

Modified: 
    clang/lib/Sema/SemaOpenMP.cpp
    clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
    clang/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
    clang/test/OpenMP/distribute_simd_reduction_messages.cpp
    clang/test/OpenMP/for_reduction_messages.cpp
    clang/test/OpenMP/for_simd_reduction_messages.cpp
    clang/test/OpenMP/master_taskloop_in_reduction_messages.cpp
    clang/test/OpenMP/master_taskloop_reduction_messages.cpp
    clang/test/OpenMP/master_taskloop_simd_in_reduction_messages.cpp
    clang/test/OpenMP/master_taskloop_simd_reduction_messages.cpp
    clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp
    clang/test/OpenMP/parallel_for_reduction_messages.cpp
    clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp
    clang/test/OpenMP/parallel_master_reduction_messages.cpp
    clang/test/OpenMP/parallel_master_taskloop_reduction_messages.cpp
    clang/test/OpenMP/parallel_master_taskloop_simd_reduction_messages.cpp
    clang/test/OpenMP/parallel_reduction_messages.cpp
    clang/test/OpenMP/parallel_sections_reduction_messages.cpp
    clang/test/OpenMP/sections_reduction_messages.cpp
    clang/test/OpenMP/simd_reduction_messages.cpp
    clang/test/OpenMP/target_parallel_for_reduction_messages.cpp
    clang/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
    clang/test/OpenMP/target_parallel_reduction_messages.cpp
    clang/test/OpenMP/target_reduction_messages.cpp
    clang/test/OpenMP/target_simd_reduction_messages.cpp
    clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
    clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
    clang/test/OpenMP/target_teams_distribute_reduction_messages.cpp
    clang/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
    clang/test/OpenMP/target_teams_reduction_messages.cpp
    clang/test/OpenMP/task_in_reduction_message.cpp
    clang/test/OpenMP/taskgroup_task_reduction_messages.cpp
    clang/test/OpenMP/taskloop_in_reduction_messages.cpp
    clang/test/OpenMP/taskloop_reduction_messages.cpp
    clang/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
    clang/test/OpenMP/taskloop_simd_reduction_messages.cpp
    clang/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
    clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
    clang/test/OpenMP/teams_distribute_reduction_messages.cpp
    clang/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
    clang/test/OpenMP/teams_reduction_messages.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index d058039c7d85b..3fcb1a7c22beb 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -16315,6 +16315,21 @@ static bool checkOMPArraySectionConstantForReduction(
   return true;
 }
 
+static BinaryOperatorKind
+getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
+  if (BOK == BO_Add)
+    return BO_AddAssign;
+  if (BOK == BO_Mul)
+    return BO_MulAssign;
+  if (BOK == BO_And)
+    return BO_AndAssign;
+  if (BOK == BO_Or)
+    return BO_OrAssign;
+  if (BOK == BO_Xor)
+    return BO_XorAssign;
+  return BOK;
+}
+
 static bool actOnOMPReductionKindClause(
     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
@@ -16840,25 +16855,35 @@ static bool actOnOMPReductionKindClause(
           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
                            S.CurFPFeatureOverrides());
     } else {
-      ReductionOp = S.BuildBinOp(
-          Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
-      if (ReductionOp.isUsable()) {
-        if (BOK != BO_LT && BOK != BO_GT) {
-          ReductionOp =
-              S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
-                           BO_Assign, LHSDRE, ReductionOp.get());
-        } else {
-          auto *ConditionalOp = new (Context)
-              ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
-                                  Type, VK_LValue, OK_Ordinary);
-          ReductionOp =
-              S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
-                           BO_Assign, LHSDRE, ConditionalOp);
+      BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
+      if (Type->isRecordType() && CombBOK != BOK) {
+        Sema::TentativeAnalysisScope Trap(S);
+        ReductionOp =
+            S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
+                         CombBOK, LHSDRE, RHSDRE);
+      }
+      if (!ReductionOp.isUsable()) {
+        ReductionOp =
+            S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
+                         LHSDRE, RHSDRE);
+        if (ReductionOp.isUsable()) {
+          if (BOK != BO_LT && BOK != BO_GT) {
+            ReductionOp =
+                S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
+                             BO_Assign, LHSDRE, ReductionOp.get());
+          } else {
+            auto *ConditionalOp = new (Context)
+                ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
+                                    RHSDRE, Type, VK_LValue, OK_Ordinary);
+            ReductionOp =
+                S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
+                             BO_Assign, LHSDRE, ConditionalOp);
+          }
         }
-        if (ReductionOp.isUsable())
-          ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
-                                              /*DiscardedValue*/ false);
       }
+      if (ReductionOp.isUsable())
+        ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
+                                            /*DiscardedValue*/ false);
       if (!ReductionOp.isUsable())
         continue;
     }

diff  --git a/clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
index 716842ae250a9..1b0bb11d62232 100644
--- a/clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
@@ -404,7 +404,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}}
+#pragma omp distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target

diff  --git a/clang/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
index 91af8bec917c0..2a71ef1b82006 100644
--- a/clang/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
@@ -403,7 +403,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target

diff  --git a/clang/test/OpenMP/distribute_simd_reduction_messages.cpp b/clang/test/OpenMP/distribute_simd_reduction_messages.cpp
index 201a4740d1d5c..5df8ec036e85b 100644
--- a/clang/test/OpenMP/distribute_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/distribute_simd_reduction_messages.cpp
@@ -409,7 +409,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}}}
+#pragma omp distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target

diff  --git a/clang/test/OpenMP/for_reduction_messages.cpp b/clang/test/OpenMP/for_reduction_messages.cpp
index 18bb2c68b824c..34f1201e7ddab 100644
--- a/clang/test/OpenMP/for_reduction_messages.cpp
+++ b/clang/test/OpenMP/for_reduction_messages.cpp
@@ -354,7 +354,7 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel

diff  --git a/clang/test/OpenMP/for_simd_reduction_messages.cpp b/clang/test/OpenMP/for_simd_reduction_messages.cpp
index bd8869e73eec9..9a60159e54ce6 100644
--- a/clang/test/OpenMP/for_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/for_simd_reduction_messages.cpp
@@ -345,7 +345,7 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel

diff  --git a/clang/test/OpenMP/master_taskloop_in_reduction_messages.cpp b/clang/test/OpenMP/master_taskloop_in_reduction_messages.cpp
index 02729711e54f7..41ac40f277d67 100644
--- a/clang/test/OpenMP/master_taskloop_in_reduction_messages.cpp
+++ b/clang/test/OpenMP/master_taskloop_in_reduction_messages.cpp
@@ -344,7 +344,7 @@ int main(int argc, char **argv) {
 #pragma omp master taskloop in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp master taskloop in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp master taskloop in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:k)

diff  --git a/clang/test/OpenMP/master_taskloop_reduction_messages.cpp b/clang/test/OpenMP/master_taskloop_reduction_messages.cpp
index b4c6970d27c96..c6b14b91d5cf1 100644
--- a/clang/test/OpenMP/master_taskloop_reduction_messages.cpp
+++ b/clang/test/OpenMP/master_taskloop_reduction_messages.cpp
@@ -312,7 +312,7 @@ int main(int argc, char **argv) {
 #pragma omp master taskloop reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp master taskloop reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp master taskloop reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp master taskloop reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/master_taskloop_simd_in_reduction_messages.cpp b/clang/test/OpenMP/master_taskloop_simd_in_reduction_messages.cpp
index 2b131bf7431ad..6453e446258b8 100644
--- a/clang/test/OpenMP/master_taskloop_simd_in_reduction_messages.cpp
+++ b/clang/test/OpenMP/master_taskloop_simd_in_reduction_messages.cpp
@@ -344,7 +344,7 @@ int main(int argc, char **argv) {
 #pragma omp master taskloop simd in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp master taskloop simd in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp master taskloop simd in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:k)

diff  --git a/clang/test/OpenMP/master_taskloop_simd_reduction_messages.cpp b/clang/test/OpenMP/master_taskloop_simd_reduction_messages.cpp
index ebc861967df11..f87df44521351 100644
--- a/clang/test/OpenMP/master_taskloop_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/master_taskloop_simd_reduction_messages.cpp
@@ -312,7 +312,7 @@ int main(int argc, char **argv) {
 #pragma omp master taskloop simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp master taskloop simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp master taskloop simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp master taskloop simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp b/clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp
index aa82783d4e5ed..f5033b63da354 100644
--- a/clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp
+++ b/clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp
@@ -195,7 +195,7 @@ void test() {
 // CHECK1-NEXT:    [[TMP20:%.*]] = bitcast float* [[REF_TMP2]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP20]]) #[[ATTR5]]
 // CHECK1-NEXT:    store float 0.000000e+00, float* [[REF_TMP2]], align 4, !tbaa [[TBAA16]]
-// CHECK1-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR8:[0-9]+]]
+// CHECK1-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR7:[0-9]+]]
 // CHECK1-NEXT:    [[TMP21:%.*]] = bitcast float* [[REF_TMP2]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP21]]) #[[ATTR5]]
 // CHECK1-NEXT:    [[TMP22:%.*]] = bitcast float* [[REF_TMP]] to i8*
@@ -259,7 +259,7 @@ void test() {
 // CHECK1-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK1-NEXT:    [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8
 // CHECK1-NEXT:    [[TMP1:%.*]] = load float*, float** [[__IM_ADDR]], align 8
-// CHECK1-NEXT:    call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR8]]
+// CHECK1-NEXT:    call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR7]]
 // CHECK1-NEXT:    ret void
 //
 //
@@ -289,7 +289,6 @@ void test() {
 // CHECK1-NEXT:    [[REF_TMP15:%.*]] = alloca float, align 4
 // CHECK1-NEXT:    [[REF_TMP16:%.*]] = alloca float, align 4
 // CHECK1-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
-// CHECK1-NEXT:    [[REF_TMP21:%.*]] = alloca %"class.std::complex", align 4
 // CHECK1-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA10]]
@@ -350,7 +349,7 @@ void test() {
 // CHECK1-NEXT:    [[TMP23:%.*]] = bitcast float* [[REF_TMP6]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP23]]) #[[ATTR5]]
 // CHECK1-NEXT:    store float 0.000000e+00, float* [[REF_TMP6]], align 4, !tbaa [[TBAA16]]
-// CHECK1-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR8]]
+// CHECK1-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR7]]
 // CHECK1-NEXT:    [[TMP24:%.*]] = bitcast float* [[REF_TMP6]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP24]]) #[[ATTR5]]
 // CHECK1-NEXT:    [[TMP25:%.*]] = bitcast float* [[REF_TMP]] to i8*
@@ -412,8 +411,8 @@ void test() {
 // CHECK1-NEXT:    [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA6]]
 // CHECK1-NEXT:    [[CONV17:%.*]] = sitofp i32 [[TMP44]] to float
 // CHECK1-NEXT:    store float [[CONV17]], float* [[REF_TMP16]], align 4, !tbaa [[TBAA16]]
-// CHECK1-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR8]]
-// CHECK1-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR8]]
+// CHECK1-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR7]]
+// CHECK1-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR7]]
 // CHECK1-NEXT:    [[TMP45:%.*]] = bitcast float* [[REF_TMP16]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP45]]) #[[ATTR5]]
 // CHECK1-NEXT:    [[TMP46:%.*]] = bitcast float* [[REF_TMP15]] to i8*
@@ -454,45 +453,32 @@ void test() {
 // CHECK1-NEXT:    [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1
 // CHECK1-NEXT:    br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]]
 // CHECK1:       .omp.reduction.then:
-// CHECK1-NEXT:    [[TMP62:%.*]] = bitcast %"class.std::complex"* [[REF_TMP21]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP62]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[CALL22:%.*]] = call %"class.std::complex" @_ZStplIfESt7complexIT_ERKS2_S4_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR8]]
-// CHECK1-NEXT:    [[TMP63:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[REF_TMP21]], i32 0, i32 0
-// CHECK1-NEXT:    [[TMP64:%.*]] = extractvalue %"class.std::complex" [[CALL22]], 0
-// CHECK1-NEXT:    store float [[TMP64]], float* [[TMP63]], align 4
-// CHECK1-NEXT:    [[TMP65:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[REF_TMP21]], i32 0, i32 1
-// CHECK1-NEXT:    [[TMP66:%.*]] = extractvalue %"class.std::complex" [[CALL22]], 1
-// CHECK1-NEXT:    store float [[TMP66]], float* [[TMP65]], align 4
-// CHECK1-NEXT:    [[TMP67:%.*]] = bitcast %"class.std::complex"* [[TMP2]] to i8*
-// CHECK1-NEXT:    [[TMP68:%.*]] = bitcast %"class.std::complex"* [[REF_TMP21]] to i8*
-// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP67]], i8* align 4 [[TMP68]], i64 8, i1 false), !tbaa.struct !18
-// CHECK1-NEXT:    [[TMP69:%.*]] = bitcast %"class.std::complex"* [[REF_TMP21]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[TMP2]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR7]]
 // CHECK1-NEXT:    call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]])
 // CHECK1-NEXT:    br label [[DOTOMP_REDUCTION_DONE]]
 // CHECK1:       .omp.reduction.done:
-// CHECK1-NEXT:    [[TMP70:%.*]] = bitcast i32* [[I7]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP71:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP71]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP72:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP73:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP74:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP74]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP75:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP75]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP62:%.*]] = bitcast i32* [[I7]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP63:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP63]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]]
 // CHECK1-NEXT:    br label [[OMP_PRECOND_END]]
 // CHECK1:       omp.precond.end:
-// CHECK1-NEXT:    [[TMP76:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP76]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP77:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP77]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP78:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP78]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP79:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP79]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]]
 // CHECK1-NEXT:    ret void
 //
 //
@@ -505,71 +491,20 @@ void test() {
 // CHECK1-NEXT:    store %"class.std::complex"* [[__C]], %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK1-NEXT:    [[TMP0:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP0]]) #[[ATTR8]]
+// CHECK1-NEXT:    [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP0]]) #[[ATTR7]]
 // CHECK1-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0
-// CHECK1-NEXT:    [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA19:![0-9]+]]
+// CHECK1-NEXT:    [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA18:![0-9]+]]
 // CHECK1-NEXT:    [[ADD:%.*]] = fadd float [[TMP1]], [[CALL]]
-// CHECK1-NEXT:    store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA19]]
+// CHECK1-NEXT:    store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA18]]
 // CHECK1-NEXT:    [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP2]]) #[[ATTR8]]
+// CHECK1-NEXT:    [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP2]]) #[[ATTR7]]
 // CHECK1-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1
-// CHECK1-NEXT:    [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA21:![0-9]+]]
+// CHECK1-NEXT:    [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA20:![0-9]+]]
 // CHECK1-NEXT:    [[ADD3:%.*]] = fadd float [[TMP3]], [[CALL2]]
-// CHECK1-NEXT:    store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA21]]
+// CHECK1-NEXT:    store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA20]]
 // CHECK1-NEXT:    ret %"class.std::complex"* [[THIS1]]
 //
 //
-// CHECK1-LABEL: define {{[^@]+}}@_ZStplIfESt7complexIT_ERKS2_S4_
-// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[__X:%.*]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[__Y:%.*]]) #[[ATTR6:[0-9]+]] comdat {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[RETVAL:%.*]] = alloca %"class.std::complex", align 4
-// CHECK1-NEXT:    [[__T2:%.*]] = alloca %"class.std::complex", align 4
-// CHECK1-NEXT:    [[__X_ADDR:%.*]] = alloca %"class.std::complex"*, align 8
-// CHECK1-NEXT:    [[__Y_ADDR:%.*]] = alloca %"class.std::complex"*, align 8
-// CHECK1-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB5:[0-9]+]])
-// CHECK1-NEXT:    [[TMP1:%.*]] = call i16 @__kmpc_parallel_level(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]])
-// CHECK1-NEXT:    [[TMP2:%.*]] = icmp eq i16 [[TMP1]], 0
-// CHECK1-NEXT:    [[TMP3:%.*]] = call i8 @__kmpc_is_spmd_exec_mode() #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP4:%.*]] = icmp ne i8 [[TMP3]], 0
-// CHECK1-NEXT:    br i1 [[TMP4]], label [[DOTSPMD:%.*]], label [[DOTNON_SPMD:%.*]]
-// CHECK1:       .spmd:
-// CHECK1-NEXT:    br label [[DOTEXIT:%.*]]
-// CHECK1:       .non-spmd:
-// CHECK1-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], i64 8, i64 256
-// CHECK1-NEXT:    [[TMP6:%.*]] = call i8* @__kmpc_data_sharing_coalesced_push_stack(i64 [[TMP5]], i16 0)
-// CHECK1-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %struct._globalized_locals_ty.2*
-// CHECK1-NEXT:    br label [[DOTEXIT]]
-// CHECK1:       .exit:
-// CHECK1-NEXT:    [[_SELECT_STACK:%.*]] = phi %struct._globalized_locals_ty.2* [ null, [[DOTSPMD]] ], [ [[TMP7]], [[DOTNON_SPMD]] ]
-// CHECK1-NEXT:    [[TMP8:%.*]] = bitcast %struct._globalized_locals_ty.2* [[_SELECT_STACK]] to %struct._globalized_locals_ty.3*
-// CHECK1-NEXT:    [[__T:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_2:%.*]], %struct._globalized_locals_ty.2* [[_SELECT_STACK]], i32 0, i32 0
-// CHECK1-NEXT:    [[NVPTX_TID:%.*]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-// CHECK1-NEXT:    [[NVPTX_LANE_ID:%.*]] = and i32 [[NVPTX_TID]], 31
-// CHECK1-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [32 x %"class.std::complex"], [32 x %"class.std::complex"]* [[__T]], i32 0, i32 [[NVPTX_LANE_ID]]
-// CHECK1-NEXT:    [[__T1:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_3:%.*]], %struct._globalized_locals_ty.3* [[TMP8]], i32 0, i32 0
-// CHECK1-NEXT:    [[TMP10:%.*]] = select i1 [[TMP2]], %"class.std::complex"* [[__T1]], %"class.std::complex"* [[TMP9]]
-// CHECK1-NEXT:    [[TMP11:%.*]] = select i1 [[TMP4]], %"class.std::complex"* [[__T2]], %"class.std::complex"* [[TMP10]]
-// CHECK1-NEXT:    store %"class.std::complex"* [[__X]], %"class.std::complex"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    store %"class.std::complex"* [[__Y]], %"class.std::complex"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[TMP12:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[TMP13:%.*]] = bitcast %"class.std::complex"* [[TMP11]] to i8*
-// CHECK1-NEXT:    [[TMP14:%.*]] = bitcast %"class.std::complex"* [[TMP12]] to i8*
-// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP13]], i8* align 4 [[TMP14]], i64 8, i1 false), !tbaa.struct !18
-// CHECK1-NEXT:    [[TMP15:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[TMP11]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP15]]) #[[ATTR8]]
-// CHECK1-NEXT:    [[TMP16:%.*]] = bitcast %"class.std::complex"* [[RETVAL]] to i8*
-// CHECK1-NEXT:    [[TMP17:%.*]] = bitcast %"class.std::complex"* [[TMP11]] to i8*
-// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP16]], i8* align 4 [[TMP17]], i64 8, i1 false), !tbaa.struct !18
-// CHECK1-NEXT:    br i1 [[TMP4]], label [[DOTEXIT4:%.*]], label [[DOTNON_SPMD3:%.*]]
-// CHECK1:       .non-spmd3:
-// CHECK1-NEXT:    [[TMP18:%.*]] = bitcast %struct._globalized_locals_ty.2* [[_SELECT_STACK]] to i8*
-// CHECK1-NEXT:    call void @__kmpc_data_sharing_pop_stack(i8* [[TMP18]])
-// CHECK1-NEXT:    br label [[DOTEXIT4]]
-// CHECK1:       .exit4:
-// CHECK1-NEXT:    [[TMP19:%.*]] = load %"class.std::complex", %"class.std::complex"* [[RETVAL]], align 4
-// CHECK1-NEXT:    ret %"class.std::complex" [[TMP19]]
-//
-//
 // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func
 // CHECK1-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR0]] {
 // CHECK1-NEXT:  entry:
@@ -639,7 +574,7 @@ void test() {
 // CHECK1-NEXT:    [[TMP45:%.*]] = bitcast i8* [[TMP43]] to %"class.std::complex"*
 // CHECK1-NEXT:    [[TMP46:%.*]] = bitcast %"class.std::complex"* [[TMP45]] to i8*
 // CHECK1-NEXT:    [[TMP47:%.*]] = bitcast %"class.std::complex"* [[TMP44]] to i8*
-// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !18
+// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !21
 // CHECK1-NEXT:    br label [[IFCONT6:%.*]]
 // CHECK1:       else5:
 // CHECK1-NEXT:    br label [[IFCONT6]]
@@ -895,7 +830,7 @@ void test() {
 // CHECK1-NEXT:    [[TMP20:%.*]] = bitcast double* [[REF_TMP2]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP20]]) #[[ATTR5]]
 // CHECK1-NEXT:    store double 0.000000e+00, double* [[REF_TMP2]], align 8, !tbaa [[TBAA22]]
-// CHECK1-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR8]]
+// CHECK1-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR7]]
 // CHECK1-NEXT:    [[TMP21:%.*]] = bitcast double* [[REF_TMP2]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP21]]) #[[ATTR5]]
 // CHECK1-NEXT:    [[TMP22:%.*]] = bitcast double* [[REF_TMP]] to i8*
@@ -959,7 +894,7 @@ void test() {
 // CHECK1-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK1-NEXT:    [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8
 // CHECK1-NEXT:    [[TMP1:%.*]] = load double*, double** [[__IM_ADDR]], align 8
-// CHECK1-NEXT:    call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR8]]
+// CHECK1-NEXT:    call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR7]]
 // CHECK1-NEXT:    ret void
 //
 //
@@ -989,7 +924,6 @@ void test() {
 // CHECK1-NEXT:    [[REF_TMP15:%.*]] = alloca double, align 8
 // CHECK1-NEXT:    [[REF_TMP16:%.*]] = alloca double, align 8
 // CHECK1-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
-// CHECK1-NEXT:    [[REF_TMP21:%.*]] = alloca %"class.std::complex.1", align 8
 // CHECK1-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA10]]
@@ -1050,7 +984,7 @@ void test() {
 // CHECK1-NEXT:    [[TMP23:%.*]] = bitcast double* [[REF_TMP6]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP23]]) #[[ATTR5]]
 // CHECK1-NEXT:    store double 0.000000e+00, double* [[REF_TMP6]], align 8, !tbaa [[TBAA22]]
-// CHECK1-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR8]]
+// CHECK1-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR7]]
 // CHECK1-NEXT:    [[TMP24:%.*]] = bitcast double* [[REF_TMP6]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP24]]) #[[ATTR5]]
 // CHECK1-NEXT:    [[TMP25:%.*]] = bitcast double* [[REF_TMP]] to i8*
@@ -1112,8 +1046,8 @@ void test() {
 // CHECK1-NEXT:    [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA6]]
 // CHECK1-NEXT:    [[CONV17:%.*]] = sitofp i32 [[TMP44]] to double
 // CHECK1-NEXT:    store double [[CONV17]], double* [[REF_TMP16]], align 8, !tbaa [[TBAA22]]
-// CHECK1-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR8]]
-// CHECK1-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR8]]
+// CHECK1-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR7]]
+// CHECK1-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR7]]
 // CHECK1-NEXT:    [[TMP45:%.*]] = bitcast double* [[REF_TMP16]] to i8*
 // CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP45]]) #[[ATTR5]]
 // CHECK1-NEXT:    [[TMP46:%.*]] = bitcast double* [[REF_TMP15]] to i8*
@@ -1154,45 +1088,32 @@ void test() {
 // CHECK1-NEXT:    [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1
 // CHECK1-NEXT:    br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]]
 // CHECK1:       .omp.reduction.then:
-// CHECK1-NEXT:    [[TMP62:%.*]] = bitcast %"class.std::complex.1"* [[REF_TMP21]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP62]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[CALL22:%.*]] = call %"class.std::complex.1" @_ZStplIdESt7complexIT_ERKS2_S4_(%"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[TMP2]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR8]]
-// CHECK1-NEXT:    [[TMP63:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[REF_TMP21]], i32 0, i32 0
-// CHECK1-NEXT:    [[TMP64:%.*]] = extractvalue %"class.std::complex.1" [[CALL22]], 0
-// CHECK1-NEXT:    store double [[TMP64]], double* [[TMP63]], align 8
-// CHECK1-NEXT:    [[TMP65:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[REF_TMP21]], i32 0, i32 1
-// CHECK1-NEXT:    [[TMP66:%.*]] = extractvalue %"class.std::complex.1" [[CALL22]], 1
-// CHECK1-NEXT:    store double [[TMP66]], double* [[TMP65]], align 8
-// CHECK1-NEXT:    [[TMP67:%.*]] = bitcast %"class.std::complex.1"* [[TMP2]] to i8*
-// CHECK1-NEXT:    [[TMP68:%.*]] = bitcast %"class.std::complex.1"* [[REF_TMP21]] to i8*
-// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP67]], i8* align 8 [[TMP68]], i64 16, i1 false), !tbaa.struct !24
-// CHECK1-NEXT:    [[TMP69:%.*]] = bitcast %"class.std::complex.1"* [[REF_TMP21]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP2]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR7]]
 // CHECK1-NEXT:    call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]])
 // CHECK1-NEXT:    br label [[DOTOMP_REDUCTION_DONE]]
 // CHECK1:       .omp.reduction.done:
-// CHECK1-NEXT:    [[TMP70:%.*]] = bitcast i32* [[I7]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP71:%.*]] = bitcast %"class.std::complex.1"* [[PARTIAL_SUM5]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP71]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP72:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP73:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP74:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP74]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP75:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP75]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP62:%.*]] = bitcast i32* [[I7]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP63:%.*]] = bitcast %"class.std::complex.1"* [[PARTIAL_SUM5]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP63]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]]
 // CHECK1-NEXT:    br label [[OMP_PRECOND_END]]
 // CHECK1:       omp.precond.end:
-// CHECK1-NEXT:    [[TMP76:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP76]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP77:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP77]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP78:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP78]]) #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP79:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
-// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP79]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
+// CHECK1-NEXT:    [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
+// CHECK1-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]]
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1205,71 +1126,20 @@ void test() {
 // CHECK1-NEXT:    store %"class.std::complex.1"* [[__C]], %"class.std::complex.1"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK1-NEXT:    [[TMP0:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP0]]) #[[ATTR8]]
+// CHECK1-NEXT:    [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP0]]) #[[ATTR7]]
 // CHECK1-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 0
-// CHECK1-NEXT:    [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA25:![0-9]+]]
+// CHECK1-NEXT:    [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24:![0-9]+]]
 // CHECK1-NEXT:    [[ADD:%.*]] = fadd double [[TMP1]], [[CALL]]
-// CHECK1-NEXT:    store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA25]]
+// CHECK1-NEXT:    store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA24]]
 // CHECK1-NEXT:    [[TMP2:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP2]]) #[[ATTR8]]
+// CHECK1-NEXT:    [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP2]]) #[[ATTR7]]
 // CHECK1-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 1
-// CHECK1-NEXT:    [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA27:![0-9]+]]
+// CHECK1-NEXT:    [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26:![0-9]+]]
 // CHECK1-NEXT:    [[ADD3:%.*]] = fadd double [[TMP3]], [[CALL2]]
-// CHECK1-NEXT:    store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA27]]
+// CHECK1-NEXT:    store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]]
 // CHECK1-NEXT:    ret %"class.std::complex.1"* [[THIS1]]
 //
 //
-// CHECK1-LABEL: define {{[^@]+}}@_ZStplIdESt7complexIT_ERKS2_S4_
-// CHECK1-SAME: (%"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[__X:%.*]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[__Y:%.*]]) #[[ATTR6]] comdat {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[RETVAL:%.*]] = alloca %"class.std::complex.1", align 8
-// CHECK1-NEXT:    [[__T2:%.*]] = alloca %"class.std::complex.1", align 8
-// CHECK1-NEXT:    [[__X_ADDR:%.*]] = alloca %"class.std::complex.1"*, align 8
-// CHECK1-NEXT:    [[__Y_ADDR:%.*]] = alloca %"class.std::complex.1"*, align 8
-// CHECK1-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB5]])
-// CHECK1-NEXT:    [[TMP1:%.*]] = call i16 @__kmpc_parallel_level(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]])
-// CHECK1-NEXT:    [[TMP2:%.*]] = icmp eq i16 [[TMP1]], 0
-// CHECK1-NEXT:    [[TMP3:%.*]] = call i8 @__kmpc_is_spmd_exec_mode() #[[ATTR5]]
-// CHECK1-NEXT:    [[TMP4:%.*]] = icmp ne i8 [[TMP3]], 0
-// CHECK1-NEXT:    br i1 [[TMP4]], label [[DOTSPMD:%.*]], label [[DOTNON_SPMD:%.*]]
-// CHECK1:       .spmd:
-// CHECK1-NEXT:    br label [[DOTEXIT:%.*]]
-// CHECK1:       .non-spmd:
-// CHECK1-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], i64 16, i64 512
-// CHECK1-NEXT:    [[TMP6:%.*]] = call i8* @__kmpc_data_sharing_coalesced_push_stack(i64 [[TMP5]], i16 0)
-// CHECK1-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %struct._globalized_locals_ty.4*
-// CHECK1-NEXT:    br label [[DOTEXIT]]
-// CHECK1:       .exit:
-// CHECK1-NEXT:    [[_SELECT_STACK:%.*]] = phi %struct._globalized_locals_ty.4* [ null, [[DOTSPMD]] ], [ [[TMP7]], [[DOTNON_SPMD]] ]
-// CHECK1-NEXT:    [[TMP8:%.*]] = bitcast %struct._globalized_locals_ty.4* [[_SELECT_STACK]] to %struct._globalized_locals_ty.5*
-// CHECK1-NEXT:    [[__T:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_4:%.*]], %struct._globalized_locals_ty.4* [[_SELECT_STACK]], i32 0, i32 0
-// CHECK1-NEXT:    [[NVPTX_TID:%.*]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-// CHECK1-NEXT:    [[NVPTX_LANE_ID:%.*]] = and i32 [[NVPTX_TID]], 31
-// CHECK1-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [32 x %"class.std::complex.1"], [32 x %"class.std::complex.1"]* [[__T]], i32 0, i32 [[NVPTX_LANE_ID]]
-// CHECK1-NEXT:    [[__T1:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_5:%.*]], %struct._globalized_locals_ty.5* [[TMP8]], i32 0, i32 0
-// CHECK1-NEXT:    [[TMP10:%.*]] = select i1 [[TMP2]], %"class.std::complex.1"* [[__T1]], %"class.std::complex.1"* [[TMP9]]
-// CHECK1-NEXT:    [[TMP11:%.*]] = select i1 [[TMP4]], %"class.std::complex.1"* [[__T2]], %"class.std::complex.1"* [[TMP10]]
-// CHECK1-NEXT:    store %"class.std::complex.1"* [[__X]], %"class.std::complex.1"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    store %"class.std::complex.1"* [[__Y]], %"class.std::complex.1"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[TMP12:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[TMP13:%.*]] = bitcast %"class.std::complex.1"* [[TMP11]] to i8*
-// CHECK1-NEXT:    [[TMP14:%.*]] = bitcast %"class.std::complex.1"* [[TMP12]] to i8*
-// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP13]], i8* align 8 [[TMP14]], i64 16, i1 false), !tbaa.struct !24
-// CHECK1-NEXT:    [[TMP15:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK1-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP11]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[TMP15]]) #[[ATTR8]]
-// CHECK1-NEXT:    [[TMP16:%.*]] = bitcast %"class.std::complex.1"* [[RETVAL]] to i8*
-// CHECK1-NEXT:    [[TMP17:%.*]] = bitcast %"class.std::complex.1"* [[TMP11]] to i8*
-// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP16]], i8* align 8 [[TMP17]], i64 16, i1 false), !tbaa.struct !24
-// CHECK1-NEXT:    br i1 [[TMP4]], label [[DOTEXIT4:%.*]], label [[DOTNON_SPMD3:%.*]]
-// CHECK1:       .non-spmd3:
-// CHECK1-NEXT:    [[TMP18:%.*]] = bitcast %struct._globalized_locals_ty.4* [[_SELECT_STACK]] to i8*
-// CHECK1-NEXT:    call void @__kmpc_data_sharing_pop_stack(i8* [[TMP18]])
-// CHECK1-NEXT:    br label [[DOTEXIT4]]
-// CHECK1:       .exit4:
-// CHECK1-NEXT:    [[TMP19:%.*]] = load %"class.std::complex.1", %"class.std::complex.1"* [[RETVAL]], align 8
-// CHECK1-NEXT:    ret %"class.std::complex.1" [[TMP19]]
-//
-//
 // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func7
 // CHECK1-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR0]] {
 // CHECK1-NEXT:  entry:
@@ -1353,7 +1223,7 @@ void test() {
 // CHECK1-NEXT:    [[TMP53:%.*]] = bitcast i8* [[TMP51]] to %"class.std::complex.1"*
 // CHECK1-NEXT:    [[TMP54:%.*]] = bitcast %"class.std::complex.1"* [[TMP53]] to i8*
 // CHECK1-NEXT:    [[TMP55:%.*]] = bitcast %"class.std::complex.1"* [[TMP52]] to i8*
-// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !24
+// CHECK1-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !27
 // CHECK1-NEXT:    br label [[IFCONT6:%.*]]
 // CHECK1:       else5:
 // CHECK1-NEXT:    br label [[IFCONT6]]
@@ -1460,11 +1330,11 @@ void test() {
 // CHECK1-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0
 // CHECK1-NEXT:    [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[TMP1:%.*]] = load float, float* [[TMP0]], align 4, !tbaa [[TBAA16]]
-// CHECK1-NEXT:    store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA19]]
+// CHECK1-NEXT:    store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA18]]
 // CHECK1-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1
 // CHECK1-NEXT:    [[TMP2:%.*]] = load float*, float** [[__IM_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[TMP3:%.*]] = load float, float* [[TMP2]], align 4, !tbaa [[TBAA16]]
-// CHECK1-NEXT:    store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA21]]
+// CHECK1-NEXT:    store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA20]]
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1475,7 +1345,7 @@ void test() {
 // CHECK1-NEXT:    store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK1-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0
-// CHECK1-NEXT:    [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA19]]
+// CHECK1-NEXT:    [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA18]]
 // CHECK1-NEXT:    ret float [[TMP0]]
 //
 //
@@ -1486,7 +1356,7 @@ void test() {
 // CHECK1-NEXT:    store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK1-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1
-// CHECK1-NEXT:    [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA21]]
+// CHECK1-NEXT:    [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA20]]
 // CHECK1-NEXT:    ret float [[TMP0]]
 //
 //
@@ -1503,11 +1373,11 @@ void test() {
 // CHECK1-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 0
 // CHECK1-NEXT:    [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !tbaa [[TBAA22]]
-// CHECK1-NEXT:    store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA25]]
+// CHECK1-NEXT:    store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA24]]
 // CHECK1-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 1
 // CHECK1-NEXT:    [[TMP2:%.*]] = load double*, double** [[__IM_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[TMP3:%.*]] = load double, double* [[TMP2]], align 8, !tbaa [[TBAA22]]
-// CHECK1-NEXT:    store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA27]]
+// CHECK1-NEXT:    store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]]
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1518,7 +1388,7 @@ void test() {
 // CHECK1-NEXT:    store %"class.std::complex.1"* [[THIS]], %"class.std::complex.1"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK1-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 0
-// CHECK1-NEXT:    [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA25]]
+// CHECK1-NEXT:    [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24]]
 // CHECK1-NEXT:    ret double [[TMP0]]
 //
 //
@@ -1529,7 +1399,7 @@ void test() {
 // CHECK1-NEXT:    store %"class.std::complex.1"* [[THIS]], %"class.std::complex.1"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK1-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK1-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 1
-// CHECK1-NEXT:    [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA27]]
+// CHECK1-NEXT:    [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26]]
 // CHECK1-NEXT:    ret double [[TMP0]]
 //
 //
@@ -1695,7 +1565,7 @@ void test() {
 // CHECK2-NEXT:    [[TMP20:%.*]] = bitcast float* [[REF_TMP2]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP20]]) #[[ATTR5]]
 // CHECK2-NEXT:    store float 0.000000e+00, float* [[REF_TMP2]], align 4, !tbaa [[TBAA16]]
-// CHECK2-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR8:[0-9]+]]
+// CHECK2-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR7:[0-9]+]]
 // CHECK2-NEXT:    [[TMP21:%.*]] = bitcast float* [[REF_TMP2]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP21]]) #[[ATTR5]]
 // CHECK2-NEXT:    [[TMP22:%.*]] = bitcast float* [[REF_TMP]] to i8*
@@ -1759,7 +1629,7 @@ void test() {
 // CHECK2-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK2-NEXT:    [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8
 // CHECK2-NEXT:    [[TMP1:%.*]] = load float*, float** [[__IM_ADDR]], align 8
-// CHECK2-NEXT:    call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR8]]
+// CHECK2-NEXT:    call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR7]]
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1789,7 +1659,6 @@ void test() {
 // CHECK2-NEXT:    [[REF_TMP15:%.*]] = alloca float, align 4
 // CHECK2-NEXT:    [[REF_TMP16:%.*]] = alloca float, align 4
 // CHECK2-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
-// CHECK2-NEXT:    [[REF_TMP21:%.*]] = alloca %"class.std::complex", align 4
 // CHECK2-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA10]]
@@ -1850,7 +1719,7 @@ void test() {
 // CHECK2-NEXT:    [[TMP23:%.*]] = bitcast float* [[REF_TMP6]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP23]]) #[[ATTR5]]
 // CHECK2-NEXT:    store float 0.000000e+00, float* [[REF_TMP6]], align 4, !tbaa [[TBAA16]]
-// CHECK2-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR8]]
+// CHECK2-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR7]]
 // CHECK2-NEXT:    [[TMP24:%.*]] = bitcast float* [[REF_TMP6]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP24]]) #[[ATTR5]]
 // CHECK2-NEXT:    [[TMP25:%.*]] = bitcast float* [[REF_TMP]] to i8*
@@ -1912,8 +1781,8 @@ void test() {
 // CHECK2-NEXT:    [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA6]]
 // CHECK2-NEXT:    [[CONV17:%.*]] = sitofp i32 [[TMP44]] to float
 // CHECK2-NEXT:    store float [[CONV17]], float* [[REF_TMP16]], align 4, !tbaa [[TBAA16]]
-// CHECK2-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR8]]
-// CHECK2-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR8]]
+// CHECK2-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR7]]
+// CHECK2-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR7]]
 // CHECK2-NEXT:    [[TMP45:%.*]] = bitcast float* [[REF_TMP16]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP45]]) #[[ATTR5]]
 // CHECK2-NEXT:    [[TMP46:%.*]] = bitcast float* [[REF_TMP15]] to i8*
@@ -1954,45 +1823,32 @@ void test() {
 // CHECK2-NEXT:    [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1
 // CHECK2-NEXT:    br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]]
 // CHECK2:       .omp.reduction.then:
-// CHECK2-NEXT:    [[TMP62:%.*]] = bitcast %"class.std::complex"* [[REF_TMP21]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP62]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[CALL22:%.*]] = call %"class.std::complex" @_ZStplIfESt7complexIT_ERKS2_S4_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR8]]
-// CHECK2-NEXT:    [[TMP63:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[REF_TMP21]], i32 0, i32 0
-// CHECK2-NEXT:    [[TMP64:%.*]] = extractvalue %"class.std::complex" [[CALL22]], 0
-// CHECK2-NEXT:    store float [[TMP64]], float* [[TMP63]], align 4
-// CHECK2-NEXT:    [[TMP65:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[REF_TMP21]], i32 0, i32 1
-// CHECK2-NEXT:    [[TMP66:%.*]] = extractvalue %"class.std::complex" [[CALL22]], 1
-// CHECK2-NEXT:    store float [[TMP66]], float* [[TMP65]], align 4
-// CHECK2-NEXT:    [[TMP67:%.*]] = bitcast %"class.std::complex"* [[TMP2]] to i8*
-// CHECK2-NEXT:    [[TMP68:%.*]] = bitcast %"class.std::complex"* [[REF_TMP21]] to i8*
-// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP67]], i8* align 4 [[TMP68]], i64 8, i1 false), !tbaa.struct !18
-// CHECK2-NEXT:    [[TMP69:%.*]] = bitcast %"class.std::complex"* [[REF_TMP21]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[TMP2]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR7]]
 // CHECK2-NEXT:    call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]])
 // CHECK2-NEXT:    br label [[DOTOMP_REDUCTION_DONE]]
 // CHECK2:       .omp.reduction.done:
-// CHECK2-NEXT:    [[TMP70:%.*]] = bitcast i32* [[I7]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP71:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP71]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP72:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP73:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP74:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP74]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP75:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP75]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP62:%.*]] = bitcast i32* [[I7]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP63:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP63]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]]
 // CHECK2-NEXT:    br label [[OMP_PRECOND_END]]
 // CHECK2:       omp.precond.end:
-// CHECK2-NEXT:    [[TMP76:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP76]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP77:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP77]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP78:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP78]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP79:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP79]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]]
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2005,71 +1861,20 @@ void test() {
 // CHECK2-NEXT:    store %"class.std::complex"* [[__C]], %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK2-NEXT:    [[TMP0:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP0]]) #[[ATTR8]]
+// CHECK2-NEXT:    [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP0]]) #[[ATTR7]]
 // CHECK2-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0
-// CHECK2-NEXT:    [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA19:![0-9]+]]
+// CHECK2-NEXT:    [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA18:![0-9]+]]
 // CHECK2-NEXT:    [[ADD:%.*]] = fadd float [[TMP1]], [[CALL]]
-// CHECK2-NEXT:    store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA19]]
+// CHECK2-NEXT:    store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA18]]
 // CHECK2-NEXT:    [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP2]]) #[[ATTR8]]
+// CHECK2-NEXT:    [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP2]]) #[[ATTR7]]
 // CHECK2-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1
-// CHECK2-NEXT:    [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA21:![0-9]+]]
+// CHECK2-NEXT:    [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA20:![0-9]+]]
 // CHECK2-NEXT:    [[ADD3:%.*]] = fadd float [[TMP3]], [[CALL2]]
-// CHECK2-NEXT:    store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA21]]
+// CHECK2-NEXT:    store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA20]]
 // CHECK2-NEXT:    ret %"class.std::complex"* [[THIS1]]
 //
 //
-// CHECK2-LABEL: define {{[^@]+}}@_ZStplIfESt7complexIT_ERKS2_S4_
-// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[__X:%.*]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[__Y:%.*]]) #[[ATTR6:[0-9]+]] comdat {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[RETVAL:%.*]] = alloca %"class.std::complex", align 4
-// CHECK2-NEXT:    [[__T2:%.*]] = alloca %"class.std::complex", align 4
-// CHECK2-NEXT:    [[__X_ADDR:%.*]] = alloca %"class.std::complex"*, align 8
-// CHECK2-NEXT:    [[__Y_ADDR:%.*]] = alloca %"class.std::complex"*, align 8
-// CHECK2-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB5:[0-9]+]])
-// CHECK2-NEXT:    [[TMP1:%.*]] = call i16 @__kmpc_parallel_level(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]])
-// CHECK2-NEXT:    [[TMP2:%.*]] = icmp eq i16 [[TMP1]], 0
-// CHECK2-NEXT:    [[TMP3:%.*]] = call i8 @__kmpc_is_spmd_exec_mode() #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP4:%.*]] = icmp ne i8 [[TMP3]], 0
-// CHECK2-NEXT:    br i1 [[TMP4]], label [[DOTSPMD:%.*]], label [[DOTNON_SPMD:%.*]]
-// CHECK2:       .spmd:
-// CHECK2-NEXT:    br label [[DOTEXIT:%.*]]
-// CHECK2:       .non-spmd:
-// CHECK2-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], i64 8, i64 256
-// CHECK2-NEXT:    [[TMP6:%.*]] = call i8* @__kmpc_data_sharing_coalesced_push_stack(i64 [[TMP5]], i16 0)
-// CHECK2-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %struct._globalized_locals_ty.2*
-// CHECK2-NEXT:    br label [[DOTEXIT]]
-// CHECK2:       .exit:
-// CHECK2-NEXT:    [[_SELECT_STACK:%.*]] = phi %struct._globalized_locals_ty.2* [ null, [[DOTSPMD]] ], [ [[TMP7]], [[DOTNON_SPMD]] ]
-// CHECK2-NEXT:    [[TMP8:%.*]] = bitcast %struct._globalized_locals_ty.2* [[_SELECT_STACK]] to %struct._globalized_locals_ty.3*
-// CHECK2-NEXT:    [[__T:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_2:%.*]], %struct._globalized_locals_ty.2* [[_SELECT_STACK]], i32 0, i32 0
-// CHECK2-NEXT:    [[NVPTX_TID:%.*]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-// CHECK2-NEXT:    [[NVPTX_LANE_ID:%.*]] = and i32 [[NVPTX_TID]], 31
-// CHECK2-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [32 x %"class.std::complex"], [32 x %"class.std::complex"]* [[__T]], i32 0, i32 [[NVPTX_LANE_ID]]
-// CHECK2-NEXT:    [[__T1:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_3:%.*]], %struct._globalized_locals_ty.3* [[TMP8]], i32 0, i32 0
-// CHECK2-NEXT:    [[TMP10:%.*]] = select i1 [[TMP2]], %"class.std::complex"* [[__T1]], %"class.std::complex"* [[TMP9]]
-// CHECK2-NEXT:    [[TMP11:%.*]] = select i1 [[TMP4]], %"class.std::complex"* [[__T2]], %"class.std::complex"* [[TMP10]]
-// CHECK2-NEXT:    store %"class.std::complex"* [[__X]], %"class.std::complex"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    store %"class.std::complex"* [[__Y]], %"class.std::complex"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[TMP12:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[TMP13:%.*]] = bitcast %"class.std::complex"* [[TMP11]] to i8*
-// CHECK2-NEXT:    [[TMP14:%.*]] = bitcast %"class.std::complex"* [[TMP12]] to i8*
-// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP13]], i8* align 4 [[TMP14]], i64 8, i1 false), !tbaa.struct !18
-// CHECK2-NEXT:    [[TMP15:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[TMP11]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP15]]) #[[ATTR8]]
-// CHECK2-NEXT:    [[TMP16:%.*]] = bitcast %"class.std::complex"* [[RETVAL]] to i8*
-// CHECK2-NEXT:    [[TMP17:%.*]] = bitcast %"class.std::complex"* [[TMP11]] to i8*
-// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP16]], i8* align 4 [[TMP17]], i64 8, i1 false), !tbaa.struct !18
-// CHECK2-NEXT:    br i1 [[TMP4]], label [[DOTEXIT4:%.*]], label [[DOTNON_SPMD3:%.*]]
-// CHECK2:       .non-spmd3:
-// CHECK2-NEXT:    [[TMP18:%.*]] = bitcast %struct._globalized_locals_ty.2* [[_SELECT_STACK]] to i8*
-// CHECK2-NEXT:    call void @__kmpc_data_sharing_pop_stack(i8* [[TMP18]])
-// CHECK2-NEXT:    br label [[DOTEXIT4]]
-// CHECK2:       .exit4:
-// CHECK2-NEXT:    [[TMP19:%.*]] = load %"class.std::complex", %"class.std::complex"* [[RETVAL]], align 4
-// CHECK2-NEXT:    ret %"class.std::complex" [[TMP19]]
-//
-//
 // CHECK2-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func
 // CHECK2-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR0]] {
 // CHECK2-NEXT:  entry:
@@ -2139,7 +1944,7 @@ void test() {
 // CHECK2-NEXT:    [[TMP45:%.*]] = bitcast i8* [[TMP43]] to %"class.std::complex"*
 // CHECK2-NEXT:    [[TMP46:%.*]] = bitcast %"class.std::complex"* [[TMP45]] to i8*
 // CHECK2-NEXT:    [[TMP47:%.*]] = bitcast %"class.std::complex"* [[TMP44]] to i8*
-// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !18
+// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !21
 // CHECK2-NEXT:    br label [[IFCONT6:%.*]]
 // CHECK2:       else5:
 // CHECK2-NEXT:    br label [[IFCONT6]]
@@ -2395,7 +2200,7 @@ void test() {
 // CHECK2-NEXT:    [[TMP20:%.*]] = bitcast double* [[REF_TMP2]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP20]]) #[[ATTR5]]
 // CHECK2-NEXT:    store double 0.000000e+00, double* [[REF_TMP2]], align 8, !tbaa [[TBAA22]]
-// CHECK2-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR8]]
+// CHECK2-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR7]]
 // CHECK2-NEXT:    [[TMP21:%.*]] = bitcast double* [[REF_TMP2]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP21]]) #[[ATTR5]]
 // CHECK2-NEXT:    [[TMP22:%.*]] = bitcast double* [[REF_TMP]] to i8*
@@ -2459,7 +2264,7 @@ void test() {
 // CHECK2-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK2-NEXT:    [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8
 // CHECK2-NEXT:    [[TMP1:%.*]] = load double*, double** [[__IM_ADDR]], align 8
-// CHECK2-NEXT:    call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR8]]
+// CHECK2-NEXT:    call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR7]]
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2489,7 +2294,6 @@ void test() {
 // CHECK2-NEXT:    [[REF_TMP15:%.*]] = alloca double, align 8
 // CHECK2-NEXT:    [[REF_TMP16:%.*]] = alloca double, align 8
 // CHECK2-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
-// CHECK2-NEXT:    [[REF_TMP21:%.*]] = alloca %"class.std::complex.1", align 8
 // CHECK2-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA10]]
@@ -2550,7 +2354,7 @@ void test() {
 // CHECK2-NEXT:    [[TMP23:%.*]] = bitcast double* [[REF_TMP6]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP23]]) #[[ATTR5]]
 // CHECK2-NEXT:    store double 0.000000e+00, double* [[REF_TMP6]], align 8, !tbaa [[TBAA22]]
-// CHECK2-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR8]]
+// CHECK2-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR7]]
 // CHECK2-NEXT:    [[TMP24:%.*]] = bitcast double* [[REF_TMP6]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP24]]) #[[ATTR5]]
 // CHECK2-NEXT:    [[TMP25:%.*]] = bitcast double* [[REF_TMP]] to i8*
@@ -2612,8 +2416,8 @@ void test() {
 // CHECK2-NEXT:    [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA6]]
 // CHECK2-NEXT:    [[CONV17:%.*]] = sitofp i32 [[TMP44]] to double
 // CHECK2-NEXT:    store double [[CONV17]], double* [[REF_TMP16]], align 8, !tbaa [[TBAA22]]
-// CHECK2-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR8]]
-// CHECK2-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR8]]
+// CHECK2-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR7]]
+// CHECK2-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR7]]
 // CHECK2-NEXT:    [[TMP45:%.*]] = bitcast double* [[REF_TMP16]] to i8*
 // CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP45]]) #[[ATTR5]]
 // CHECK2-NEXT:    [[TMP46:%.*]] = bitcast double* [[REF_TMP15]] to i8*
@@ -2654,45 +2458,32 @@ void test() {
 // CHECK2-NEXT:    [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1
 // CHECK2-NEXT:    br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]]
 // CHECK2:       .omp.reduction.then:
-// CHECK2-NEXT:    [[TMP62:%.*]] = bitcast %"class.std::complex.1"* [[REF_TMP21]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP62]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[CALL22:%.*]] = call %"class.std::complex.1" @_ZStplIdESt7complexIT_ERKS2_S4_(%"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[TMP2]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR8]]
-// CHECK2-NEXT:    [[TMP63:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[REF_TMP21]], i32 0, i32 0
-// CHECK2-NEXT:    [[TMP64:%.*]] = extractvalue %"class.std::complex.1" [[CALL22]], 0
-// CHECK2-NEXT:    store double [[TMP64]], double* [[TMP63]], align 8
-// CHECK2-NEXT:    [[TMP65:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[REF_TMP21]], i32 0, i32 1
-// CHECK2-NEXT:    [[TMP66:%.*]] = extractvalue %"class.std::complex.1" [[CALL22]], 1
-// CHECK2-NEXT:    store double [[TMP66]], double* [[TMP65]], align 8
-// CHECK2-NEXT:    [[TMP67:%.*]] = bitcast %"class.std::complex.1"* [[TMP2]] to i8*
-// CHECK2-NEXT:    [[TMP68:%.*]] = bitcast %"class.std::complex.1"* [[REF_TMP21]] to i8*
-// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP67]], i8* align 8 [[TMP68]], i64 16, i1 false), !tbaa.struct !24
-// CHECK2-NEXT:    [[TMP69:%.*]] = bitcast %"class.std::complex.1"* [[REF_TMP21]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP2]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR7]]
 // CHECK2-NEXT:    call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]])
 // CHECK2-NEXT:    br label [[DOTOMP_REDUCTION_DONE]]
 // CHECK2:       .omp.reduction.done:
-// CHECK2-NEXT:    [[TMP70:%.*]] = bitcast i32* [[I7]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP71:%.*]] = bitcast %"class.std::complex.1"* [[PARTIAL_SUM5]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP71]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP72:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP73:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP74:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP74]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP75:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP75]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP62:%.*]] = bitcast i32* [[I7]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP63:%.*]] = bitcast %"class.std::complex.1"* [[PARTIAL_SUM5]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP63]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]]
 // CHECK2-NEXT:    br label [[OMP_PRECOND_END]]
 // CHECK2:       omp.precond.end:
-// CHECK2-NEXT:    [[TMP76:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP76]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP77:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP77]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP78:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP78]]) #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP79:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
-// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP79]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
+// CHECK2-NEXT:    [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
+// CHECK2-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]]
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2705,71 +2496,20 @@ void test() {
 // CHECK2-NEXT:    store %"class.std::complex.1"* [[__C]], %"class.std::complex.1"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK2-NEXT:    [[TMP0:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP0]]) #[[ATTR8]]
+// CHECK2-NEXT:    [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP0]]) #[[ATTR7]]
 // CHECK2-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 0
-// CHECK2-NEXT:    [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA25:![0-9]+]]
+// CHECK2-NEXT:    [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24:![0-9]+]]
 // CHECK2-NEXT:    [[ADD:%.*]] = fadd double [[TMP1]], [[CALL]]
-// CHECK2-NEXT:    store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA25]]
+// CHECK2-NEXT:    store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA24]]
 // CHECK2-NEXT:    [[TMP2:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP2]]) #[[ATTR8]]
+// CHECK2-NEXT:    [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP2]]) #[[ATTR7]]
 // CHECK2-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 1
-// CHECK2-NEXT:    [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA27:![0-9]+]]
+// CHECK2-NEXT:    [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26:![0-9]+]]
 // CHECK2-NEXT:    [[ADD3:%.*]] = fadd double [[TMP3]], [[CALL2]]
-// CHECK2-NEXT:    store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA27]]
+// CHECK2-NEXT:    store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]]
 // CHECK2-NEXT:    ret %"class.std::complex.1"* [[THIS1]]
 //
 //
-// CHECK2-LABEL: define {{[^@]+}}@_ZStplIdESt7complexIT_ERKS2_S4_
-// CHECK2-SAME: (%"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[__X:%.*]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[__Y:%.*]]) #[[ATTR6]] comdat {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[RETVAL:%.*]] = alloca %"class.std::complex.1", align 8
-// CHECK2-NEXT:    [[__T2:%.*]] = alloca %"class.std::complex.1", align 8
-// CHECK2-NEXT:    [[__X_ADDR:%.*]] = alloca %"class.std::complex.1"*, align 8
-// CHECK2-NEXT:    [[__Y_ADDR:%.*]] = alloca %"class.std::complex.1"*, align 8
-// CHECK2-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB5]])
-// CHECK2-NEXT:    [[TMP1:%.*]] = call i16 @__kmpc_parallel_level(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]])
-// CHECK2-NEXT:    [[TMP2:%.*]] = icmp eq i16 [[TMP1]], 0
-// CHECK2-NEXT:    [[TMP3:%.*]] = call i8 @__kmpc_is_spmd_exec_mode() #[[ATTR5]]
-// CHECK2-NEXT:    [[TMP4:%.*]] = icmp ne i8 [[TMP3]], 0
-// CHECK2-NEXT:    br i1 [[TMP4]], label [[DOTSPMD:%.*]], label [[DOTNON_SPMD:%.*]]
-// CHECK2:       .spmd:
-// CHECK2-NEXT:    br label [[DOTEXIT:%.*]]
-// CHECK2:       .non-spmd:
-// CHECK2-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], i64 16, i64 512
-// CHECK2-NEXT:    [[TMP6:%.*]] = call i8* @__kmpc_data_sharing_coalesced_push_stack(i64 [[TMP5]], i16 0)
-// CHECK2-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %struct._globalized_locals_ty.4*
-// CHECK2-NEXT:    br label [[DOTEXIT]]
-// CHECK2:       .exit:
-// CHECK2-NEXT:    [[_SELECT_STACK:%.*]] = phi %struct._globalized_locals_ty.4* [ null, [[DOTSPMD]] ], [ [[TMP7]], [[DOTNON_SPMD]] ]
-// CHECK2-NEXT:    [[TMP8:%.*]] = bitcast %struct._globalized_locals_ty.4* [[_SELECT_STACK]] to %struct._globalized_locals_ty.5*
-// CHECK2-NEXT:    [[__T:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_4:%.*]], %struct._globalized_locals_ty.4* [[_SELECT_STACK]], i32 0, i32 0
-// CHECK2-NEXT:    [[NVPTX_TID:%.*]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-// CHECK2-NEXT:    [[NVPTX_LANE_ID:%.*]] = and i32 [[NVPTX_TID]], 31
-// CHECK2-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [32 x %"class.std::complex.1"], [32 x %"class.std::complex.1"]* [[__T]], i32 0, i32 [[NVPTX_LANE_ID]]
-// CHECK2-NEXT:    [[__T1:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_5:%.*]], %struct._globalized_locals_ty.5* [[TMP8]], i32 0, i32 0
-// CHECK2-NEXT:    [[TMP10:%.*]] = select i1 [[TMP2]], %"class.std::complex.1"* [[__T1]], %"class.std::complex.1"* [[TMP9]]
-// CHECK2-NEXT:    [[TMP11:%.*]] = select i1 [[TMP4]], %"class.std::complex.1"* [[__T2]], %"class.std::complex.1"* [[TMP10]]
-// CHECK2-NEXT:    store %"class.std::complex.1"* [[__X]], %"class.std::complex.1"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    store %"class.std::complex.1"* [[__Y]], %"class.std::complex.1"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[TMP12:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[TMP13:%.*]] = bitcast %"class.std::complex.1"* [[TMP11]] to i8*
-// CHECK2-NEXT:    [[TMP14:%.*]] = bitcast %"class.std::complex.1"* [[TMP12]] to i8*
-// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP13]], i8* align 8 [[TMP14]], i64 16, i1 false), !tbaa.struct !24
-// CHECK2-NEXT:    [[TMP15:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK2-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP11]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[TMP15]]) #[[ATTR8]]
-// CHECK2-NEXT:    [[TMP16:%.*]] = bitcast %"class.std::complex.1"* [[RETVAL]] to i8*
-// CHECK2-NEXT:    [[TMP17:%.*]] = bitcast %"class.std::complex.1"* [[TMP11]] to i8*
-// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP16]], i8* align 8 [[TMP17]], i64 16, i1 false), !tbaa.struct !24
-// CHECK2-NEXT:    br i1 [[TMP4]], label [[DOTEXIT4:%.*]], label [[DOTNON_SPMD3:%.*]]
-// CHECK2:       .non-spmd3:
-// CHECK2-NEXT:    [[TMP18:%.*]] = bitcast %struct._globalized_locals_ty.4* [[_SELECT_STACK]] to i8*
-// CHECK2-NEXT:    call void @__kmpc_data_sharing_pop_stack(i8* [[TMP18]])
-// CHECK2-NEXT:    br label [[DOTEXIT4]]
-// CHECK2:       .exit4:
-// CHECK2-NEXT:    [[TMP19:%.*]] = load %"class.std::complex.1", %"class.std::complex.1"* [[RETVAL]], align 8
-// CHECK2-NEXT:    ret %"class.std::complex.1" [[TMP19]]
-//
-//
 // CHECK2-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func7
 // CHECK2-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR0]] {
 // CHECK2-NEXT:  entry:
@@ -2853,7 +2593,7 @@ void test() {
 // CHECK2-NEXT:    [[TMP53:%.*]] = bitcast i8* [[TMP51]] to %"class.std::complex.1"*
 // CHECK2-NEXT:    [[TMP54:%.*]] = bitcast %"class.std::complex.1"* [[TMP53]] to i8*
 // CHECK2-NEXT:    [[TMP55:%.*]] = bitcast %"class.std::complex.1"* [[TMP52]] to i8*
-// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !24
+// CHECK2-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !27
 // CHECK2-NEXT:    br label [[IFCONT6:%.*]]
 // CHECK2:       else5:
 // CHECK2-NEXT:    br label [[IFCONT6]]
@@ -2960,11 +2700,11 @@ void test() {
 // CHECK2-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0
 // CHECK2-NEXT:    [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[TMP1:%.*]] = load float, float* [[TMP0]], align 4, !tbaa [[TBAA16]]
-// CHECK2-NEXT:    store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA19]]
+// CHECK2-NEXT:    store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA18]]
 // CHECK2-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1
 // CHECK2-NEXT:    [[TMP2:%.*]] = load float*, float** [[__IM_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[TMP3:%.*]] = load float, float* [[TMP2]], align 4, !tbaa [[TBAA16]]
-// CHECK2-NEXT:    store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA21]]
+// CHECK2-NEXT:    store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA20]]
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2975,7 +2715,7 @@ void test() {
 // CHECK2-NEXT:    store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK2-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0
-// CHECK2-NEXT:    [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA19]]
+// CHECK2-NEXT:    [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA18]]
 // CHECK2-NEXT:    ret float [[TMP0]]
 //
 //
@@ -2986,7 +2726,7 @@ void test() {
 // CHECK2-NEXT:    store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK2-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1
-// CHECK2-NEXT:    [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA21]]
+// CHECK2-NEXT:    [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA20]]
 // CHECK2-NEXT:    ret float [[TMP0]]
 //
 //
@@ -3003,11 +2743,11 @@ void test() {
 // CHECK2-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 0
 // CHECK2-NEXT:    [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !tbaa [[TBAA22]]
-// CHECK2-NEXT:    store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA25]]
+// CHECK2-NEXT:    store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA24]]
 // CHECK2-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 1
 // CHECK2-NEXT:    [[TMP2:%.*]] = load double*, double** [[__IM_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[TMP3:%.*]] = load double, double* [[TMP2]], align 8, !tbaa [[TBAA22]]
-// CHECK2-NEXT:    store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA27]]
+// CHECK2-NEXT:    store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]]
 // CHECK2-NEXT:    ret void
 //
 //
@@ -3018,7 +2758,7 @@ void test() {
 // CHECK2-NEXT:    store %"class.std::complex.1"* [[THIS]], %"class.std::complex.1"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK2-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 0
-// CHECK2-NEXT:    [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA25]]
+// CHECK2-NEXT:    [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24]]
 // CHECK2-NEXT:    ret double [[TMP0]]
 //
 //
@@ -3029,7 +2769,7 @@ void test() {
 // CHECK2-NEXT:    store %"class.std::complex.1"* [[THIS]], %"class.std::complex.1"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK2-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK2-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 1
-// CHECK2-NEXT:    [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA27]]
+// CHECK2-NEXT:    [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26]]
 // CHECK2-NEXT:    ret double [[TMP0]]
 //
 //
@@ -3195,7 +2935,7 @@ void test() {
 // CHECK3-NEXT:    [[TMP20:%.*]] = bitcast float* [[REF_TMP2]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP20]]) #[[ATTR5]]
 // CHECK3-NEXT:    store float 0.000000e+00, float* [[REF_TMP2]], align 4, !tbaa [[TBAA16]]
-// CHECK3-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR8:[0-9]+]]
+// CHECK3-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR7:[0-9]+]]
 // CHECK3-NEXT:    [[TMP21:%.*]] = bitcast float* [[REF_TMP2]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP21]]) #[[ATTR5]]
 // CHECK3-NEXT:    [[TMP22:%.*]] = bitcast float* [[REF_TMP]] to i8*
@@ -3259,7 +2999,7 @@ void test() {
 // CHECK3-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK3-NEXT:    [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8
 // CHECK3-NEXT:    [[TMP1:%.*]] = load float*, float** [[__IM_ADDR]], align 8
-// CHECK3-NEXT:    call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR8]]
+// CHECK3-NEXT:    call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR7]]
 // CHECK3-NEXT:    ret void
 //
 //
@@ -3289,7 +3029,6 @@ void test() {
 // CHECK3-NEXT:    [[REF_TMP15:%.*]] = alloca float, align 4
 // CHECK3-NEXT:    [[REF_TMP16:%.*]] = alloca float, align 4
 // CHECK3-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
-// CHECK3-NEXT:    [[REF_TMP21:%.*]] = alloca %"class.std::complex", align 4
 // CHECK3-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA10]]
@@ -3350,7 +3089,7 @@ void test() {
 // CHECK3-NEXT:    [[TMP23:%.*]] = bitcast float* [[REF_TMP6]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP23]]) #[[ATTR5]]
 // CHECK3-NEXT:    store float 0.000000e+00, float* [[REF_TMP6]], align 4, !tbaa [[TBAA16]]
-// CHECK3-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR8]]
+// CHECK3-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR7]]
 // CHECK3-NEXT:    [[TMP24:%.*]] = bitcast float* [[REF_TMP6]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP24]]) #[[ATTR5]]
 // CHECK3-NEXT:    [[TMP25:%.*]] = bitcast float* [[REF_TMP]] to i8*
@@ -3412,8 +3151,8 @@ void test() {
 // CHECK3-NEXT:    [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA6]]
 // CHECK3-NEXT:    [[CONV17:%.*]] = sitofp i32 [[TMP44]] to float
 // CHECK3-NEXT:    store float [[CONV17]], float* [[REF_TMP16]], align 4, !tbaa [[TBAA16]]
-// CHECK3-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR8]]
-// CHECK3-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR8]]
+// CHECK3-NEXT:    call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR7]]
+// CHECK3-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR7]]
 // CHECK3-NEXT:    [[TMP45:%.*]] = bitcast float* [[REF_TMP16]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP45]]) #[[ATTR5]]
 // CHECK3-NEXT:    [[TMP46:%.*]] = bitcast float* [[REF_TMP15]] to i8*
@@ -3454,45 +3193,32 @@ void test() {
 // CHECK3-NEXT:    [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1
 // CHECK3-NEXT:    br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]]
 // CHECK3:       .omp.reduction.then:
-// CHECK3-NEXT:    [[TMP62:%.*]] = bitcast %"class.std::complex"* [[REF_TMP21]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP62]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[CALL22:%.*]] = call %"class.std::complex" @_ZStplIfESt7complexIT_ERKS2_S4_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR8]]
-// CHECK3-NEXT:    [[TMP63:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[REF_TMP21]], i32 0, i32 0
-// CHECK3-NEXT:    [[TMP64:%.*]] = extractvalue %"class.std::complex" [[CALL22]], 0
-// CHECK3-NEXT:    store float [[TMP64]], float* [[TMP63]], align 4
-// CHECK3-NEXT:    [[TMP65:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[REF_TMP21]], i32 0, i32 1
-// CHECK3-NEXT:    [[TMP66:%.*]] = extractvalue %"class.std::complex" [[CALL22]], 1
-// CHECK3-NEXT:    store float [[TMP66]], float* [[TMP65]], align 4
-// CHECK3-NEXT:    [[TMP67:%.*]] = bitcast %"class.std::complex"* [[TMP2]] to i8*
-// CHECK3-NEXT:    [[TMP68:%.*]] = bitcast %"class.std::complex"* [[REF_TMP21]] to i8*
-// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP67]], i8* align 4 [[TMP68]], i64 8, i1 false), !tbaa.struct !18
-// CHECK3-NEXT:    [[TMP69:%.*]] = bitcast %"class.std::complex"* [[REF_TMP21]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[TMP2]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR7]]
 // CHECK3-NEXT:    call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]])
 // CHECK3-NEXT:    br label [[DOTOMP_REDUCTION_DONE]]
 // CHECK3:       .omp.reduction.done:
-// CHECK3-NEXT:    [[TMP70:%.*]] = bitcast i32* [[I7]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP71:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP71]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP72:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP73:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP74:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP74]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP75:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP75]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP62:%.*]] = bitcast i32* [[I7]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP63:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP63]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]]
 // CHECK3-NEXT:    br label [[OMP_PRECOND_END]]
 // CHECK3:       omp.precond.end:
-// CHECK3-NEXT:    [[TMP76:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP76]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP77:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP77]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP78:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP78]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP79:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP79]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]]
 // CHECK3-NEXT:    ret void
 //
 //
@@ -3505,71 +3231,20 @@ void test() {
 // CHECK3-NEXT:    store %"class.std::complex"* [[__C]], %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK3-NEXT:    [[TMP0:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP0]]) #[[ATTR8]]
+// CHECK3-NEXT:    [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP0]]) #[[ATTR7]]
 // CHECK3-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0
-// CHECK3-NEXT:    [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA19:![0-9]+]]
+// CHECK3-NEXT:    [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA18:![0-9]+]]
 // CHECK3-NEXT:    [[ADD:%.*]] = fadd float [[TMP1]], [[CALL]]
-// CHECK3-NEXT:    store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA19]]
+// CHECK3-NEXT:    store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA18]]
 // CHECK3-NEXT:    [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP2]]) #[[ATTR8]]
+// CHECK3-NEXT:    [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull dereferenceable(8) [[TMP2]]) #[[ATTR7]]
 // CHECK3-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1
-// CHECK3-NEXT:    [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA21:![0-9]+]]
+// CHECK3-NEXT:    [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA20:![0-9]+]]
 // CHECK3-NEXT:    [[ADD3:%.*]] = fadd float [[TMP3]], [[CALL2]]
-// CHECK3-NEXT:    store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA21]]
+// CHECK3-NEXT:    store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA20]]
 // CHECK3-NEXT:    ret %"class.std::complex"* [[THIS1]]
 //
 //
-// CHECK3-LABEL: define {{[^@]+}}@_ZStplIfESt7complexIT_ERKS2_S4_
-// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[__X:%.*]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[__Y:%.*]]) #[[ATTR6:[0-9]+]] comdat {
-// CHECK3-NEXT:  entry:
-// CHECK3-NEXT:    [[RETVAL:%.*]] = alloca %"class.std::complex", align 4
-// CHECK3-NEXT:    [[__T2:%.*]] = alloca %"class.std::complex", align 4
-// CHECK3-NEXT:    [[__X_ADDR:%.*]] = alloca %"class.std::complex"*, align 8
-// CHECK3-NEXT:    [[__Y_ADDR:%.*]] = alloca %"class.std::complex"*, align 8
-// CHECK3-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB5:[0-9]+]])
-// CHECK3-NEXT:    [[TMP1:%.*]] = call i16 @__kmpc_parallel_level(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]])
-// CHECK3-NEXT:    [[TMP2:%.*]] = icmp eq i16 [[TMP1]], 0
-// CHECK3-NEXT:    [[TMP3:%.*]] = call i8 @__kmpc_is_spmd_exec_mode() #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP4:%.*]] = icmp ne i8 [[TMP3]], 0
-// CHECK3-NEXT:    br i1 [[TMP4]], label [[DOTSPMD:%.*]], label [[DOTNON_SPMD:%.*]]
-// CHECK3:       .spmd:
-// CHECK3-NEXT:    br label [[DOTEXIT:%.*]]
-// CHECK3:       .non-spmd:
-// CHECK3-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], i64 8, i64 256
-// CHECK3-NEXT:    [[TMP6:%.*]] = call i8* @__kmpc_data_sharing_coalesced_push_stack(i64 [[TMP5]], i16 0)
-// CHECK3-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %struct._globalized_locals_ty.2*
-// CHECK3-NEXT:    br label [[DOTEXIT]]
-// CHECK3:       .exit:
-// CHECK3-NEXT:    [[_SELECT_STACK:%.*]] = phi %struct._globalized_locals_ty.2* [ null, [[DOTSPMD]] ], [ [[TMP7]], [[DOTNON_SPMD]] ]
-// CHECK3-NEXT:    [[TMP8:%.*]] = bitcast %struct._globalized_locals_ty.2* [[_SELECT_STACK]] to %struct._globalized_locals_ty.3*
-// CHECK3-NEXT:    [[__T:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_2:%.*]], %struct._globalized_locals_ty.2* [[_SELECT_STACK]], i32 0, i32 0
-// CHECK3-NEXT:    [[NVPTX_TID:%.*]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-// CHECK3-NEXT:    [[NVPTX_LANE_ID:%.*]] = and i32 [[NVPTX_TID]], 31
-// CHECK3-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [32 x %"class.std::complex"], [32 x %"class.std::complex"]* [[__T]], i32 0, i32 [[NVPTX_LANE_ID]]
-// CHECK3-NEXT:    [[__T1:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_3:%.*]], %struct._globalized_locals_ty.3* [[TMP8]], i32 0, i32 0
-// CHECK3-NEXT:    [[TMP10:%.*]] = select i1 [[TMP2]], %"class.std::complex"* [[__T1]], %"class.std::complex"* [[TMP9]]
-// CHECK3-NEXT:    [[TMP11:%.*]] = select i1 [[TMP4]], %"class.std::complex"* [[__T2]], %"class.std::complex"* [[TMP10]]
-// CHECK3-NEXT:    store %"class.std::complex"* [[__X]], %"class.std::complex"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    store %"class.std::complex"* [[__Y]], %"class.std::complex"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[TMP12:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[TMP13:%.*]] = bitcast %"class.std::complex"* [[TMP11]] to i8*
-// CHECK3-NEXT:    [[TMP14:%.*]] = bitcast %"class.std::complex"* [[TMP12]] to i8*
-// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP13]], i8* align 4 [[TMP14]], i64 8, i1 false), !tbaa.struct !18
-// CHECK3-NEXT:    [[TMP15:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull dereferenceable(8) [[TMP11]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP15]]) #[[ATTR8]]
-// CHECK3-NEXT:    [[TMP16:%.*]] = bitcast %"class.std::complex"* [[RETVAL]] to i8*
-// CHECK3-NEXT:    [[TMP17:%.*]] = bitcast %"class.std::complex"* [[TMP11]] to i8*
-// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP16]], i8* align 4 [[TMP17]], i64 8, i1 false), !tbaa.struct !18
-// CHECK3-NEXT:    br i1 [[TMP4]], label [[DOTEXIT4:%.*]], label [[DOTNON_SPMD3:%.*]]
-// CHECK3:       .non-spmd3:
-// CHECK3-NEXT:    [[TMP18:%.*]] = bitcast %struct._globalized_locals_ty.2* [[_SELECT_STACK]] to i8*
-// CHECK3-NEXT:    call void @__kmpc_data_sharing_pop_stack(i8* [[TMP18]])
-// CHECK3-NEXT:    br label [[DOTEXIT4]]
-// CHECK3:       .exit4:
-// CHECK3-NEXT:    [[TMP19:%.*]] = load %"class.std::complex", %"class.std::complex"* [[RETVAL]], align 4
-// CHECK3-NEXT:    ret %"class.std::complex" [[TMP19]]
-//
-//
 // CHECK3-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func
 // CHECK3-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR0]] {
 // CHECK3-NEXT:  entry:
@@ -3639,7 +3314,7 @@ void test() {
 // CHECK3-NEXT:    [[TMP45:%.*]] = bitcast i8* [[TMP43]] to %"class.std::complex"*
 // CHECK3-NEXT:    [[TMP46:%.*]] = bitcast %"class.std::complex"* [[TMP45]] to i8*
 // CHECK3-NEXT:    [[TMP47:%.*]] = bitcast %"class.std::complex"* [[TMP44]] to i8*
-// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !18
+// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !21
 // CHECK3-NEXT:    br label [[IFCONT6:%.*]]
 // CHECK3:       else5:
 // CHECK3-NEXT:    br label [[IFCONT6]]
@@ -3895,7 +3570,7 @@ void test() {
 // CHECK3-NEXT:    [[TMP20:%.*]] = bitcast double* [[REF_TMP2]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP20]]) #[[ATTR5]]
 // CHECK3-NEXT:    store double 0.000000e+00, double* [[REF_TMP2]], align 8, !tbaa [[TBAA22]]
-// CHECK3-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR8]]
+// CHECK3-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR7]]
 // CHECK3-NEXT:    [[TMP21:%.*]] = bitcast double* [[REF_TMP2]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP21]]) #[[ATTR5]]
 // CHECK3-NEXT:    [[TMP22:%.*]] = bitcast double* [[REF_TMP]] to i8*
@@ -3959,7 +3634,7 @@ void test() {
 // CHECK3-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK3-NEXT:    [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8
 // CHECK3-NEXT:    [[TMP1:%.*]] = load double*, double** [[__IM_ADDR]], align 8
-// CHECK3-NEXT:    call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR8]]
+// CHECK3-NEXT:    call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR7]]
 // CHECK3-NEXT:    ret void
 //
 //
@@ -3989,7 +3664,6 @@ void test() {
 // CHECK3-NEXT:    [[REF_TMP15:%.*]] = alloca double, align 8
 // CHECK3-NEXT:    [[REF_TMP16:%.*]] = alloca double, align 8
 // CHECK3-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
-// CHECK3-NEXT:    [[REF_TMP21:%.*]] = alloca %"class.std::complex.1", align 8
 // CHECK3-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA10]]
@@ -4050,7 +3724,7 @@ void test() {
 // CHECK3-NEXT:    [[TMP23:%.*]] = bitcast double* [[REF_TMP6]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP23]]) #[[ATTR5]]
 // CHECK3-NEXT:    store double 0.000000e+00, double* [[REF_TMP6]], align 8, !tbaa [[TBAA22]]
-// CHECK3-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR8]]
+// CHECK3-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR7]]
 // CHECK3-NEXT:    [[TMP24:%.*]] = bitcast double* [[REF_TMP6]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP24]]) #[[ATTR5]]
 // CHECK3-NEXT:    [[TMP25:%.*]] = bitcast double* [[REF_TMP]] to i8*
@@ -4112,8 +3786,8 @@ void test() {
 // CHECK3-NEXT:    [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA6]]
 // CHECK3-NEXT:    [[CONV17:%.*]] = sitofp i32 [[TMP44]] to double
 // CHECK3-NEXT:    store double [[CONV17]], double* [[REF_TMP16]], align 8, !tbaa [[TBAA22]]
-// CHECK3-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR8]]
-// CHECK3-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR8]]
+// CHECK3-NEXT:    call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.1"* nonnull dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR7]]
+// CHECK3-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR7]]
 // CHECK3-NEXT:    [[TMP45:%.*]] = bitcast double* [[REF_TMP16]] to i8*
 // CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP45]]) #[[ATTR5]]
 // CHECK3-NEXT:    [[TMP46:%.*]] = bitcast double* [[REF_TMP15]] to i8*
@@ -4154,45 +3828,32 @@ void test() {
 // CHECK3-NEXT:    [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1
 // CHECK3-NEXT:    br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]]
 // CHECK3:       .omp.reduction.then:
-// CHECK3-NEXT:    [[TMP62:%.*]] = bitcast %"class.std::complex.1"* [[REF_TMP21]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP62]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[CALL22:%.*]] = call %"class.std::complex.1" @_ZStplIdESt7complexIT_ERKS2_S4_(%"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[TMP2]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR8]]
-// CHECK3-NEXT:    [[TMP63:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[REF_TMP21]], i32 0, i32 0
-// CHECK3-NEXT:    [[TMP64:%.*]] = extractvalue %"class.std::complex.1" [[CALL22]], 0
-// CHECK3-NEXT:    store double [[TMP64]], double* [[TMP63]], align 8
-// CHECK3-NEXT:    [[TMP65:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[REF_TMP21]], i32 0, i32 1
-// CHECK3-NEXT:    [[TMP66:%.*]] = extractvalue %"class.std::complex.1" [[CALL22]], 1
-// CHECK3-NEXT:    store double [[TMP66]], double* [[TMP65]], align 8
-// CHECK3-NEXT:    [[TMP67:%.*]] = bitcast %"class.std::complex.1"* [[TMP2]] to i8*
-// CHECK3-NEXT:    [[TMP68:%.*]] = bitcast %"class.std::complex.1"* [[REF_TMP21]] to i8*
-// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP67]], i8* align 8 [[TMP68]], i64 16, i1 false), !tbaa.struct !24
-// CHECK3-NEXT:    [[TMP69:%.*]] = bitcast %"class.std::complex.1"* [[REF_TMP21]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP2]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR7]]
 // CHECK3-NEXT:    call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]])
 // CHECK3-NEXT:    br label [[DOTOMP_REDUCTION_DONE]]
 // CHECK3:       .omp.reduction.done:
-// CHECK3-NEXT:    [[TMP70:%.*]] = bitcast i32* [[I7]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP71:%.*]] = bitcast %"class.std::complex.1"* [[PARTIAL_SUM5]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP71]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP72:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP73:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP74:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP74]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP75:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP75]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP62:%.*]] = bitcast i32* [[I7]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP63:%.*]] = bitcast %"class.std::complex.1"* [[PARTIAL_SUM5]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP63]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]]
 // CHECK3-NEXT:    br label [[OMP_PRECOND_END]]
 // CHECK3:       omp.precond.end:
-// CHECK3-NEXT:    [[TMP76:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP76]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP77:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP77]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP78:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP78]]) #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP79:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
-// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP79]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]]
+// CHECK3-NEXT:    [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8*
+// CHECK3-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]]
 // CHECK3-NEXT:    ret void
 //
 //
@@ -4205,71 +3866,20 @@ void test() {
 // CHECK3-NEXT:    store %"class.std::complex.1"* [[__C]], %"class.std::complex.1"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK3-NEXT:    [[TMP0:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP0]]) #[[ATTR8]]
+// CHECK3-NEXT:    [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP0]]) #[[ATTR7]]
 // CHECK3-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 0
-// CHECK3-NEXT:    [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA25:![0-9]+]]
+// CHECK3-NEXT:    [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24:![0-9]+]]
 // CHECK3-NEXT:    [[ADD:%.*]] = fadd double [[TMP1]], [[CALL]]
-// CHECK3-NEXT:    store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA25]]
+// CHECK3-NEXT:    store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA24]]
 // CHECK3-NEXT:    [[TMP2:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__C_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP2]]) #[[ATTR8]]
+// CHECK3-NEXT:    [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP2]]) #[[ATTR7]]
 // CHECK3-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 1
-// CHECK3-NEXT:    [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA27:![0-9]+]]
+// CHECK3-NEXT:    [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26:![0-9]+]]
 // CHECK3-NEXT:    [[ADD3:%.*]] = fadd double [[TMP3]], [[CALL2]]
-// CHECK3-NEXT:    store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA27]]
+// CHECK3-NEXT:    store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]]
 // CHECK3-NEXT:    ret %"class.std::complex.1"* [[THIS1]]
 //
 //
-// CHECK3-LABEL: define {{[^@]+}}@_ZStplIdESt7complexIT_ERKS2_S4_
-// CHECK3-SAME: (%"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[__X:%.*]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[__Y:%.*]]) #[[ATTR6]] comdat {
-// CHECK3-NEXT:  entry:
-// CHECK3-NEXT:    [[RETVAL:%.*]] = alloca %"class.std::complex.1", align 8
-// CHECK3-NEXT:    [[__T2:%.*]] = alloca %"class.std::complex.1", align 8
-// CHECK3-NEXT:    [[__X_ADDR:%.*]] = alloca %"class.std::complex.1"*, align 8
-// CHECK3-NEXT:    [[__Y_ADDR:%.*]] = alloca %"class.std::complex.1"*, align 8
-// CHECK3-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB5]])
-// CHECK3-NEXT:    [[TMP1:%.*]] = call i16 @__kmpc_parallel_level(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]])
-// CHECK3-NEXT:    [[TMP2:%.*]] = icmp eq i16 [[TMP1]], 0
-// CHECK3-NEXT:    [[TMP3:%.*]] = call i8 @__kmpc_is_spmd_exec_mode() #[[ATTR5]]
-// CHECK3-NEXT:    [[TMP4:%.*]] = icmp ne i8 [[TMP3]], 0
-// CHECK3-NEXT:    br i1 [[TMP4]], label [[DOTSPMD:%.*]], label [[DOTNON_SPMD:%.*]]
-// CHECK3:       .spmd:
-// CHECK3-NEXT:    br label [[DOTEXIT:%.*]]
-// CHECK3:       .non-spmd:
-// CHECK3-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], i64 16, i64 512
-// CHECK3-NEXT:    [[TMP6:%.*]] = call i8* @__kmpc_data_sharing_coalesced_push_stack(i64 [[TMP5]], i16 0)
-// CHECK3-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %struct._globalized_locals_ty.4*
-// CHECK3-NEXT:    br label [[DOTEXIT]]
-// CHECK3:       .exit:
-// CHECK3-NEXT:    [[_SELECT_STACK:%.*]] = phi %struct._globalized_locals_ty.4* [ null, [[DOTSPMD]] ], [ [[TMP7]], [[DOTNON_SPMD]] ]
-// CHECK3-NEXT:    [[TMP8:%.*]] = bitcast %struct._globalized_locals_ty.4* [[_SELECT_STACK]] to %struct._globalized_locals_ty.5*
-// CHECK3-NEXT:    [[__T:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_4:%.*]], %struct._globalized_locals_ty.4* [[_SELECT_STACK]], i32 0, i32 0
-// CHECK3-NEXT:    [[NVPTX_TID:%.*]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-// CHECK3-NEXT:    [[NVPTX_LANE_ID:%.*]] = and i32 [[NVPTX_TID]], 31
-// CHECK3-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [32 x %"class.std::complex.1"], [32 x %"class.std::complex.1"]* [[__T]], i32 0, i32 [[NVPTX_LANE_ID]]
-// CHECK3-NEXT:    [[__T1:%.*]] = getelementptr inbounds [[STRUCT__GLOBALIZED_LOCALS_TY_5:%.*]], %struct._globalized_locals_ty.5* [[TMP8]], i32 0, i32 0
-// CHECK3-NEXT:    [[TMP10:%.*]] = select i1 [[TMP2]], %"class.std::complex.1"* [[__T1]], %"class.std::complex.1"* [[TMP9]]
-// CHECK3-NEXT:    [[TMP11:%.*]] = select i1 [[TMP4]], %"class.std::complex.1"* [[__T2]], %"class.std::complex.1"* [[TMP10]]
-// CHECK3-NEXT:    store %"class.std::complex.1"* [[__X]], %"class.std::complex.1"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    store %"class.std::complex.1"* [[__Y]], %"class.std::complex.1"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[TMP12:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__X_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[TMP13:%.*]] = bitcast %"class.std::complex.1"* [[TMP11]] to i8*
-// CHECK3-NEXT:    [[TMP14:%.*]] = bitcast %"class.std::complex.1"* [[TMP12]] to i8*
-// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP13]], i8* align 8 [[TMP14]], i64 16, i1 false), !tbaa.struct !24
-// CHECK3-NEXT:    [[TMP15:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[__Y_ADDR]], align 8, !tbaa [[TBAA10]]
-// CHECK3-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.1"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.1"* nonnull dereferenceable(16) [[TMP11]], %"class.std::complex.1"* nonnull align 8 dereferenceable(16) [[TMP15]]) #[[ATTR8]]
-// CHECK3-NEXT:    [[TMP16:%.*]] = bitcast %"class.std::complex.1"* [[RETVAL]] to i8*
-// CHECK3-NEXT:    [[TMP17:%.*]] = bitcast %"class.std::complex.1"* [[TMP11]] to i8*
-// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP16]], i8* align 8 [[TMP17]], i64 16, i1 false), !tbaa.struct !24
-// CHECK3-NEXT:    br i1 [[TMP4]], label [[DOTEXIT4:%.*]], label [[DOTNON_SPMD3:%.*]]
-// CHECK3:       .non-spmd3:
-// CHECK3-NEXT:    [[TMP18:%.*]] = bitcast %struct._globalized_locals_ty.4* [[_SELECT_STACK]] to i8*
-// CHECK3-NEXT:    call void @__kmpc_data_sharing_pop_stack(i8* [[TMP18]])
-// CHECK3-NEXT:    br label [[DOTEXIT4]]
-// CHECK3:       .exit4:
-// CHECK3-NEXT:    [[TMP19:%.*]] = load %"class.std::complex.1", %"class.std::complex.1"* [[RETVAL]], align 8
-// CHECK3-NEXT:    ret %"class.std::complex.1" [[TMP19]]
-//
-//
 // CHECK3-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func7
 // CHECK3-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR0]] {
 // CHECK3-NEXT:  entry:
@@ -4353,7 +3963,7 @@ void test() {
 // CHECK3-NEXT:    [[TMP53:%.*]] = bitcast i8* [[TMP51]] to %"class.std::complex.1"*
 // CHECK3-NEXT:    [[TMP54:%.*]] = bitcast %"class.std::complex.1"* [[TMP53]] to i8*
 // CHECK3-NEXT:    [[TMP55:%.*]] = bitcast %"class.std::complex.1"* [[TMP52]] to i8*
-// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !24
+// CHECK3-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !27
 // CHECK3-NEXT:    br label [[IFCONT6:%.*]]
 // CHECK3:       else5:
 // CHECK3-NEXT:    br label [[IFCONT6]]
@@ -4460,11 +4070,11 @@ void test() {
 // CHECK3-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0
 // CHECK3-NEXT:    [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[TMP1:%.*]] = load float, float* [[TMP0]], align 4, !tbaa [[TBAA16]]
-// CHECK3-NEXT:    store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA19]]
+// CHECK3-NEXT:    store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA18]]
 // CHECK3-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1
 // CHECK3-NEXT:    [[TMP2:%.*]] = load float*, float** [[__IM_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[TMP3:%.*]] = load float, float* [[TMP2]], align 4, !tbaa [[TBAA16]]
-// CHECK3-NEXT:    store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA21]]
+// CHECK3-NEXT:    store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA20]]
 // CHECK3-NEXT:    ret void
 //
 //
@@ -4475,7 +4085,7 @@ void test() {
 // CHECK3-NEXT:    store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK3-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0
-// CHECK3-NEXT:    [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA19]]
+// CHECK3-NEXT:    [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA18]]
 // CHECK3-NEXT:    ret float [[TMP0]]
 //
 //
@@ -4486,7 +4096,7 @@ void test() {
 // CHECK3-NEXT:    store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8
 // CHECK3-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1
-// CHECK3-NEXT:    [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA21]]
+// CHECK3-NEXT:    [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA20]]
 // CHECK3-NEXT:    ret float [[TMP0]]
 //
 //
@@ -4503,11 +4113,11 @@ void test() {
 // CHECK3-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 0
 // CHECK3-NEXT:    [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !tbaa [[TBAA22]]
-// CHECK3-NEXT:    store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA25]]
+// CHECK3-NEXT:    store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA24]]
 // CHECK3-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 1
 // CHECK3-NEXT:    [[TMP2:%.*]] = load double*, double** [[__IM_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[TMP3:%.*]] = load double, double* [[TMP2]], align 8, !tbaa [[TBAA22]]
-// CHECK3-NEXT:    store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA27]]
+// CHECK3-NEXT:    store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]]
 // CHECK3-NEXT:    ret void
 //
 //
@@ -4518,7 +4128,7 @@ void test() {
 // CHECK3-NEXT:    store %"class.std::complex.1"* [[THIS]], %"class.std::complex.1"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK3-NEXT:    [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 0
-// CHECK3-NEXT:    [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA25]]
+// CHECK3-NEXT:    [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24]]
 // CHECK3-NEXT:    ret double [[TMP0]]
 //
 //
@@ -4529,6 +4139,6 @@ void test() {
 // CHECK3-NEXT:    store %"class.std::complex.1"* [[THIS]], %"class.std::complex.1"** [[THIS_ADDR]], align 8, !tbaa [[TBAA10]]
 // CHECK3-NEXT:    [[THIS1:%.*]] = load %"class.std::complex.1"*, %"class.std::complex.1"** [[THIS_ADDR]], align 8
 // CHECK3-NEXT:    [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.1", %"class.std::complex.1"* [[THIS1]], i32 0, i32 1
-// CHECK3-NEXT:    [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA27]]
+// CHECK3-NEXT:    [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26]]
 // CHECK3-NEXT:    ret double [[TMP0]]
 //

diff  --git a/clang/test/OpenMP/parallel_for_reduction_messages.cpp b/clang/test/OpenMP/parallel_for_reduction_messages.cpp
index b22585a85fbbb..9f2f4510b8db8 100644
--- a/clang/test/OpenMP/parallel_for_reduction_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_reduction_messages.cpp
@@ -301,7 +301,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp
index d5daa64ca4145..8bf7e96d0b815 100644
--- a/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp
@@ -293,7 +293,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/parallel_master_reduction_messages.cpp b/clang/test/OpenMP/parallel_master_reduction_messages.cpp
index 2313181fe76c7..f5344fc183753 100644
--- a/clang/test/OpenMP/parallel_master_reduction_messages.cpp
+++ b/clang/test/OpenMP/parallel_master_reduction_messages.cpp
@@ -349,7 +349,7 @@ int main(int argc, char **argv) {
   {
     foo();
   }
-#pragma omp parallel master reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp parallel master reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   {
     foo();
   }

diff  --git a/clang/test/OpenMP/parallel_master_taskloop_reduction_messages.cpp b/clang/test/OpenMP/parallel_master_taskloop_reduction_messages.cpp
index c5ad633eac72b..acf0d8f07ca1e 100644
--- a/clang/test/OpenMP/parallel_master_taskloop_reduction_messages.cpp
+++ b/clang/test/OpenMP/parallel_master_taskloop_reduction_messages.cpp
@@ -312,7 +312,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel master taskloop reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel master taskloop reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp parallel master taskloop reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel master taskloop reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/parallel_master_taskloop_simd_reduction_messages.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_reduction_messages.cpp
index 88ae4575ed92a..fb201d5b98b27 100644
--- a/clang/test/OpenMP/parallel_master_taskloop_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/parallel_master_taskloop_simd_reduction_messages.cpp
@@ -312,7 +312,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel master taskloop simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel master taskloop simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp parallel master taskloop simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel master taskloop simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/parallel_reduction_messages.cpp b/clang/test/OpenMP/parallel_reduction_messages.cpp
index 12b34a4de07ba..3fdb9d4a3ca89 100644
--- a/clang/test/OpenMP/parallel_reduction_messages.cpp
+++ b/clang/test/OpenMP/parallel_reduction_messages.cpp
@@ -245,7 +245,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
 #pragma omp parallel reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
   foo();

diff  --git a/clang/test/OpenMP/parallel_sections_reduction_messages.cpp b/clang/test/OpenMP/parallel_sections_reduction_messages.cpp
index 79ba5a3014f6b..c5dbc91171af5 100644
--- a/clang/test/OpenMP/parallel_sections_reduction_messages.cpp
+++ b/clang/test/OpenMP/parallel_sections_reduction_messages.cpp
@@ -349,7 +349,7 @@ int main(int argc, char **argv) {
   {
     foo();
   }
-#pragma omp parallel sections reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp parallel sections reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   {
     foo();
   }

diff  --git a/clang/test/OpenMP/reduction_compound_op.cpp b/clang/test/OpenMP/reduction_compound_op.cpp
new file mode 100644
index 0000000000000..461bc6860e514
--- /dev/null
+++ b/clang/test/OpenMP/reduction_compound_op.cpp
@@ -0,0 +1,2558 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
+//RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp -DNORM \
+//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix NORM
+
+//RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp -DCOMP \
+//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix COMP
+
+// Prefer compound operators since that is what the spec seems to say.
+//RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp -DNORM -DCOMP \
+//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix COMP
+
+//RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp-simd -DNORM \
+//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix SIMD-ONLY
+
+//RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp-simd -DCOMP \
+//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix SIMD-ONLY
+
+//RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp-simd -DNORM -DCOMP \
+//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix SIMD-ONLY
+
+// SIMD-ONLY-NOT: {{__kmpc|__tgt}}
+
+struct Point {
+  int x = 0;
+  int y = 0;
+#if NORM
+  Point operator+(Point const &other) const;
+  Point operator-(Point const &other) const;
+  Point operator*(Point const &other) const;
+  Point operator&(Point const &other) const;
+  Point operator|(Point const &other) const;
+  Point operator^(Point const &other) const;
+#endif
+  Point operator&&(Point const &other) const;
+  Point operator||(Point const &other) const;
+  Point &operator=(Point const &other);
+#if COMP
+  Point &operator+=(Point const &other);
+  Point &operator*=(Point const &other);
+  Point &operator&=(Point const &other);
+  Point &operator|=(Point const &other);
+  Point &operator^=(Point const &other);
+#endif
+};
+
+void work(Point &P, int N, Point const *Points);
+
+void foo(int N, Point const *Points) {
+  Point Red;
+  #pragma omp parallel for reduction(+: Red)
+  for (unsigned I = 0; I < N; ++I)
+    work(Red, I, Points);
+
+  #pragma omp parallel for reduction(-: Red)
+  for (unsigned I = 0; I < N; ++I)
+    work(Red, I, Points);
+
+  #pragma omp parallel for reduction(*: Red)
+  for (unsigned I = 0; I < N; ++I)
+    work(Red, I, Points);
+
+  #pragma omp parallel for reduction(&: Red)
+  for (unsigned I = 0; I < N; ++I)
+    work(Red, I, Points);
+
+  #pragma omp parallel for reduction(|: Red)
+  for (unsigned I = 0; I < N; ++I)
+    work(Red, I, Points);
+
+  #pragma omp parallel for reduction(^: Red)
+  for (unsigned I = 0; I < N; ++I)
+    work(Red, I, Points);
+
+  #pragma omp parallel for reduction(&&: Red)
+  for (unsigned I = 0; I < N; ++I)
+    work(Red, I, Points);
+
+  #pragma omp parallel for reduction(||: Red)
+  for (unsigned I = 0; I < N; ++I)
+    work(Red, I, Points);
+}
+// NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point
+// NORM-SAME: (i32 [[N:%.*]], %struct.Point* [[POINTS:%.*]]) #[[ATTR0:[0-9]+]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    [[RED:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    store i32 [[N]], i32* [[N_ADDR]], align 4
+// NORM-NEXT:    store %struct.Point* [[POINTS]], %struct.Point** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED]]) #[[ATTR4:[0-9]+]]
+// NORM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// NORM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..1 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// NORM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// NORM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// NORM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..7 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// NORM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..9 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// NORM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..11 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// NORM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..13 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@_ZN5PointC1Ev
+// NORM-SAME: (%struct.Point* nonnull dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    store %struct.Point* [[THIS]], %struct.Point** [[THIS_ADDR]], align 8
+// NORM-NEXT:    [[THIS1:%.*]] = load %struct.Point*, %struct.Point** [[THIS_ADDR]], align 8
+// NORM-NEXT:    call void @_ZN5PointC2Ev(%struct.Point* nonnull dereferenceable(8) [[THIS1]]) #[[ATTR4]]
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp_outlined.
+// NORM-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2:[0-9]+]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// NORM-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// NORM-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// NORM-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// NORM-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// NORM-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// NORM-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 0, i32* [[I]], align 4
+// NORM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// NORM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// NORM:       omp.precond.then:
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// NORM-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// NORM-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// NORM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// NORM-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// NORM:       cond.true:
+// NORM-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    br label [[COND_END:%.*]]
+// NORM:       cond.false:
+// NORM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    br label [[COND_END]]
+// NORM:       cond.end:
+// NORM-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// NORM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// NORM:       omp.inner.for.cond:
+// NORM-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// NORM-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// NORM-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// NORM:       omp.inner.for.body:
+// NORM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// NORM-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// NORM-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// NORM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// NORM:       omp.body.continue:
+// NORM-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// NORM:       omp.inner.for.inc:
+// NORM-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// NORM-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// NORM:       omp.inner.for.end:
+// NORM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// NORM:       omp.loop.exit:
+// NORM-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// NORM-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// NORM-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// NORM-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// NORM-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// NORM-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// NORM-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// NORM-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// NORM-NEXT:    ]
+// NORM:       .omp.reduction.case1:
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.case2:
+// NORM-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// NORM-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointplERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// NORM-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// NORM-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.default:
+// NORM-NEXT:    br label [[OMP_PRECOND_END]]
+// NORM:       omp.precond.end:
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
+// NORM-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5:[0-9]+]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// NORM-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// NORM-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// NORM-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// NORM-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// NORM-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// NORM-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp_outlined..1
+// NORM-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// NORM-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// NORM-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// NORM-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// NORM-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// NORM-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// NORM-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 0, i32* [[I]], align 4
+// NORM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// NORM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// NORM:       omp.precond.then:
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// NORM-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// NORM-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// NORM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// NORM-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// NORM:       cond.true:
+// NORM-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    br label [[COND_END:%.*]]
+// NORM:       cond.false:
+// NORM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    br label [[COND_END]]
+// NORM:       cond.end:
+// NORM-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// NORM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// NORM:       omp.inner.for.cond:
+// NORM-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// NORM-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// NORM-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// NORM:       omp.inner.for.body:
+// NORM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// NORM-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// NORM-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// NORM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// NORM:       omp.body.continue:
+// NORM-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// NORM:       omp.inner.for.inc:
+// NORM-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// NORM-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// NORM:       omp.inner.for.end:
+// NORM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// NORM:       omp.loop.exit:
+// NORM-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// NORM-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// NORM-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// NORM-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// NORM-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// NORM-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.2, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// NORM-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// NORM-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// NORM-NEXT:    ]
+// NORM:       .omp.reduction.case1:
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.case2:
+// NORM-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// NORM-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointplERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// NORM-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// NORM-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.default:
+// NORM-NEXT:    br label [[OMP_PRECOND_END]]
+// NORM:       omp.precond.end:
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.2
+// NORM-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// NORM-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// NORM-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// NORM-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// NORM-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// NORM-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// NORM-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp_outlined..3
+// NORM-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// NORM-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// NORM-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// NORM-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// NORM-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// NORM-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// NORM-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 0, i32* [[I]], align 4
+// NORM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// NORM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// NORM:       omp.precond.then:
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// NORM-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// NORM-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// NORM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// NORM-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// NORM:       cond.true:
+// NORM-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    br label [[COND_END:%.*]]
+// NORM:       cond.false:
+// NORM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    br label [[COND_END]]
+// NORM:       cond.end:
+// NORM-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// NORM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// NORM:       omp.inner.for.cond:
+// NORM-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// NORM-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// NORM-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// NORM:       omp.inner.for.body:
+// NORM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// NORM-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// NORM-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// NORM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// NORM:       omp.body.continue:
+// NORM-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// NORM:       omp.inner.for.inc:
+// NORM-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// NORM-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// NORM:       omp.inner.for.end:
+// NORM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// NORM:       omp.loop.exit:
+// NORM-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// NORM-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// NORM-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// NORM-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// NORM-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// NORM-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.4, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// NORM-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// NORM-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// NORM-NEXT:    ]
+// NORM:       .omp.reduction.case1:
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointmlERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.case2:
+// NORM-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// NORM-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointmlERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// NORM-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// NORM-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.default:
+// NORM-NEXT:    br label [[OMP_PRECOND_END]]
+// NORM:       omp.precond.end:
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.4
+// NORM-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// NORM-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// NORM-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// NORM-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// NORM-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// NORM-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointmlERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// NORM-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp_outlined..5
+// NORM-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// NORM-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// NORM-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// NORM-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// NORM-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// NORM-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// NORM-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 0, i32* [[I]], align 4
+// NORM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// NORM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// NORM:       omp.precond.then:
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// NORM-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// NORM-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// NORM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// NORM-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// NORM:       cond.true:
+// NORM-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    br label [[COND_END:%.*]]
+// NORM:       cond.false:
+// NORM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    br label [[COND_END]]
+// NORM:       cond.end:
+// NORM-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// NORM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// NORM:       omp.inner.for.cond:
+// NORM-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// NORM-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// NORM-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// NORM:       omp.inner.for.body:
+// NORM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// NORM-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// NORM-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// NORM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// NORM:       omp.body.continue:
+// NORM-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// NORM:       omp.inner.for.inc:
+// NORM-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// NORM-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// NORM:       omp.inner.for.end:
+// NORM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// NORM:       omp.loop.exit:
+// NORM-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// NORM-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// NORM-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// NORM-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// NORM-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// NORM-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.6, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// NORM-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// NORM-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// NORM-NEXT:    ]
+// NORM:       .omp.reduction.case1:
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointanERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.case2:
+// NORM-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// NORM-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointanERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// NORM-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// NORM-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.default:
+// NORM-NEXT:    br label [[OMP_PRECOND_END]]
+// NORM:       omp.precond.end:
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.6
+// NORM-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// NORM-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// NORM-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// NORM-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// NORM-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// NORM-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointanERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// NORM-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp_outlined..7
+// NORM-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// NORM-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// NORM-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// NORM-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// NORM-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// NORM-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// NORM-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 0, i32* [[I]], align 4
+// NORM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// NORM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// NORM:       omp.precond.then:
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// NORM-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// NORM-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// NORM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// NORM-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// NORM:       cond.true:
+// NORM-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    br label [[COND_END:%.*]]
+// NORM:       cond.false:
+// NORM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    br label [[COND_END]]
+// NORM:       cond.end:
+// NORM-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// NORM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// NORM:       omp.inner.for.cond:
+// NORM-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// NORM-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// NORM-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// NORM:       omp.inner.for.body:
+// NORM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// NORM-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// NORM-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// NORM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// NORM:       omp.body.continue:
+// NORM-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// NORM:       omp.inner.for.inc:
+// NORM-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// NORM-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// NORM:       omp.inner.for.end:
+// NORM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// NORM:       omp.loop.exit:
+// NORM-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// NORM-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// NORM-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// NORM-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// NORM-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// NORM-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.8, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// NORM-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// NORM-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// NORM-NEXT:    ]
+// NORM:       .omp.reduction.case1:
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointorERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.case2:
+// NORM-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// NORM-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointorERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// NORM-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// NORM-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.default:
+// NORM-NEXT:    br label [[OMP_PRECOND_END]]
+// NORM:       omp.precond.end:
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.8
+// NORM-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// NORM-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// NORM-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// NORM-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// NORM-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// NORM-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointorERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// NORM-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp_outlined..9
+// NORM-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// NORM-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// NORM-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// NORM-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// NORM-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// NORM-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// NORM-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 0, i32* [[I]], align 4
+// NORM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// NORM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// NORM:       omp.precond.then:
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// NORM-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// NORM-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// NORM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// NORM-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// NORM:       cond.true:
+// NORM-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    br label [[COND_END:%.*]]
+// NORM:       cond.false:
+// NORM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    br label [[COND_END]]
+// NORM:       cond.end:
+// NORM-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// NORM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// NORM:       omp.inner.for.cond:
+// NORM-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// NORM-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// NORM-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// NORM:       omp.inner.for.body:
+// NORM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// NORM-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// NORM-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// NORM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// NORM:       omp.body.continue:
+// NORM-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// NORM:       omp.inner.for.inc:
+// NORM-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// NORM-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// NORM:       omp.inner.for.end:
+// NORM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// NORM:       omp.loop.exit:
+// NORM-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// NORM-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// NORM-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// NORM-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// NORM-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// NORM-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.10, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// NORM-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// NORM-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// NORM-NEXT:    ]
+// NORM:       .omp.reduction.case1:
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointeoERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.case2:
+// NORM-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// NORM-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointeoERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// NORM-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// NORM-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.default:
+// NORM-NEXT:    br label [[OMP_PRECOND_END]]
+// NORM:       omp.precond.end:
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.10
+// NORM-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// NORM-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// NORM-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// NORM-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// NORM-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// NORM-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointeoERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// NORM-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp_outlined..11
+// NORM-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// NORM-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// NORM-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// NORM-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// NORM-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// NORM-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// NORM-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 0, i32* [[I]], align 4
+// NORM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// NORM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// NORM:       omp.precond.then:
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// NORM-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// NORM-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// NORM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// NORM-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// NORM:       cond.true:
+// NORM-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    br label [[COND_END:%.*]]
+// NORM:       cond.false:
+// NORM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    br label [[COND_END]]
+// NORM:       cond.end:
+// NORM-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// NORM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// NORM:       omp.inner.for.cond:
+// NORM-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// NORM-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// NORM-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// NORM:       omp.inner.for.body:
+// NORM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// NORM-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// NORM-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// NORM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// NORM:       omp.body.continue:
+// NORM-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// NORM:       omp.inner.for.inc:
+// NORM-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// NORM-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// NORM:       omp.inner.for.end:
+// NORM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// NORM:       omp.loop.exit:
+// NORM-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// NORM-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// NORM-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// NORM-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// NORM-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// NORM-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.12, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// NORM-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// NORM-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// NORM-NEXT:    ]
+// NORM:       .omp.reduction.case1:
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.case2:
+// NORM-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// NORM-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointaaERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// NORM-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// NORM-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.default:
+// NORM-NEXT:    br label [[OMP_PRECOND_END]]
+// NORM:       omp.precond.end:
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.12
+// NORM-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// NORM-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// NORM-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// NORM-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// NORM-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// NORM-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// NORM-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp_outlined..13
+// NORM-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// NORM-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[I:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// NORM-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// NORM-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// NORM-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// NORM-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// NORM-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// NORM-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// NORM-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// NORM-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 0, i32* [[I]], align 4
+// NORM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// NORM-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// NORM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// NORM:       omp.precond.then:
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// NORM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// NORM-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// NORM-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// NORM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// NORM-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// NORM:       cond.true:
+// NORM-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// NORM-NEXT:    br label [[COND_END:%.*]]
+// NORM:       cond.false:
+// NORM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    br label [[COND_END]]
+// NORM:       cond.end:
+// NORM-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// NORM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// NORM-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// NORM:       omp.inner.for.cond:
+// NORM-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// NORM-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// NORM-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// NORM-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// NORM:       omp.inner.for.body:
+// NORM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// NORM-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// NORM-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// NORM-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// NORM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// NORM:       omp.body.continue:
+// NORM-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// NORM:       omp.inner.for.inc:
+// NORM-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// NORM-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// NORM-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// NORM:       omp.inner.for.end:
+// NORM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// NORM:       omp.loop.exit:
+// NORM-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// NORM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// NORM-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// NORM-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// NORM-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// NORM-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// NORM-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.14, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// NORM-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// NORM-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// NORM-NEXT:    ]
+// NORM:       .omp.reduction.case1:
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.case2:
+// NORM-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// NORM-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// NORM-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointooERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// NORM-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// NORM-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// NORM-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// NORM:       .omp.reduction.default:
+// NORM-NEXT:    br label [[OMP_PRECOND_END]]
+// NORM:       omp.precond.end:
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.14
+// NORM-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// NORM-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// NORM-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// NORM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// NORM-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// NORM-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// NORM-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// NORM-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// NORM-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// NORM-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// NORM-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// NORM-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// NORM-NEXT:    ret void
+//
+//
+// NORM-LABEL: define {{[^@]+}}@_ZN5PointC2Ev
+// NORM-SAME: (%struct.Point* nonnull dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 {
+// NORM-NEXT:  entry:
+// NORM-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Point*, align 8
+// NORM-NEXT:    store %struct.Point* [[THIS]], %struct.Point** [[THIS_ADDR]], align 8
+// NORM-NEXT:    [[THIS1:%.*]] = load %struct.Point*, %struct.Point** [[THIS_ADDR]], align 8
+// NORM-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_POINT:%.*]], %struct.Point* [[THIS1]], i32 0, i32 0
+// NORM-NEXT:    store i32 0, i32* [[X]], align 4
+// NORM-NEXT:    [[Y:%.*]] = getelementptr inbounds [[STRUCT_POINT]], %struct.Point* [[THIS1]], i32 0, i32 1
+// NORM-NEXT:    store i32 0, i32* [[Y]], align 4
+// NORM-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point
+// COMP-SAME: (i32 [[N:%.*]], %struct.Point* [[POINTS:%.*]]) #[[ATTR0:[0-9]+]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    [[RED:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    store i32 [[N]], i32* [[N_ADDR]], align 4
+// COMP-NEXT:    store %struct.Point* [[POINTS]], %struct.Point** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED]]) #[[ATTR4:[0-9]+]]
+// COMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// COMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..1 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// COMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// COMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// COMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..7 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// COMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..9 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// COMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..11 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// COMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.Point*, %struct.Point**)* @.omp_outlined..13 to void (i32*, i32*, ...)*), i32* [[N_ADDR]], %struct.Point* [[RED]], %struct.Point** [[POINTS_ADDR]])
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@_ZN5PointC1Ev
+// COMP-SAME: (%struct.Point* nonnull dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    store %struct.Point* [[THIS]], %struct.Point** [[THIS_ADDR]], align 8
+// COMP-NEXT:    [[THIS1:%.*]] = load %struct.Point*, %struct.Point** [[THIS_ADDR]], align 8
+// COMP-NEXT:    call void @_ZN5PointC2Ev(%struct.Point* nonnull dereferenceable(8) [[THIS1]]) #[[ATTR4]]
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp_outlined.
+// COMP-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2:[0-9]+]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// COMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// COMP-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// COMP-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// COMP-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// COMP-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// COMP-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// COMP-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 0, i32* [[I]], align 4
+// COMP-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// COMP-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// COMP:       omp.precond.then:
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// COMP-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// COMP-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// COMP-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// COMP-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// COMP:       cond.true:
+// COMP-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    br label [[COND_END:%.*]]
+// COMP:       cond.false:
+// COMP-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    br label [[COND_END]]
+// COMP:       cond.end:
+// COMP-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// COMP-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// COMP:       omp.inner.for.cond:
+// COMP-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// COMP-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// COMP-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// COMP:       omp.inner.for.body:
+// COMP-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// COMP-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// COMP-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// COMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// COMP:       omp.body.continue:
+// COMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// COMP:       omp.inner.for.inc:
+// COMP-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// COMP-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// COMP:       omp.inner.for.end:
+// COMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// COMP:       omp.loop.exit:
+// COMP-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// COMP-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// COMP-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// COMP-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// COMP-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// COMP-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// COMP-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// COMP-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// COMP-NEXT:    ]
+// COMP:       .omp.reduction.case1:
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointpLERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.case2:
+// COMP-NEXT:    [[TMP28:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4
+// COMP-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointpLERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.default:
+// COMP-NEXT:    br label [[OMP_PRECOND_END]]
+// COMP:       omp.precond.end:
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
+// COMP-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5:[0-9]+]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// COMP-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// COMP-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// COMP-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// COMP-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// COMP-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointpLERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp_outlined..1
+// COMP-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// COMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// COMP-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// COMP-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// COMP-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// COMP-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// COMP-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// COMP-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 0, i32* [[I]], align 4
+// COMP-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// COMP-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// COMP:       omp.precond.then:
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// COMP-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// COMP-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// COMP-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// COMP-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// COMP:       cond.true:
+// COMP-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    br label [[COND_END:%.*]]
+// COMP:       cond.false:
+// COMP-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    br label [[COND_END]]
+// COMP:       cond.end:
+// COMP-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// COMP-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// COMP:       omp.inner.for.cond:
+// COMP-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// COMP-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// COMP-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// COMP:       omp.inner.for.body:
+// COMP-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// COMP-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// COMP-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// COMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// COMP:       omp.body.continue:
+// COMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// COMP:       omp.inner.for.inc:
+// COMP-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// COMP-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// COMP:       omp.inner.for.end:
+// COMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// COMP:       omp.loop.exit:
+// COMP-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// COMP-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// COMP-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// COMP-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// COMP-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// COMP-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.2, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// COMP-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// COMP-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// COMP-NEXT:    ]
+// COMP:       .omp.reduction.case1:
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointpLERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.case2:
+// COMP-NEXT:    [[TMP28:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4
+// COMP-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointpLERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.default:
+// COMP-NEXT:    br label [[OMP_PRECOND_END]]
+// COMP:       omp.precond.end:
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.2
+// COMP-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// COMP-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// COMP-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// COMP-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// COMP-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// COMP-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointpLERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp_outlined..3
+// COMP-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// COMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// COMP-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// COMP-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// COMP-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// COMP-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// COMP-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// COMP-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 0, i32* [[I]], align 4
+// COMP-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// COMP-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// COMP:       omp.precond.then:
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// COMP-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// COMP-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// COMP-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// COMP-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// COMP:       cond.true:
+// COMP-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    br label [[COND_END:%.*]]
+// COMP:       cond.false:
+// COMP-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    br label [[COND_END]]
+// COMP:       cond.end:
+// COMP-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// COMP-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// COMP:       omp.inner.for.cond:
+// COMP-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// COMP-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// COMP-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// COMP:       omp.inner.for.body:
+// COMP-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// COMP-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// COMP-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// COMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// COMP:       omp.body.continue:
+// COMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// COMP:       omp.inner.for.inc:
+// COMP-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// COMP-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// COMP:       omp.inner.for.end:
+// COMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// COMP:       omp.loop.exit:
+// COMP-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// COMP-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// COMP-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// COMP-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// COMP-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// COMP-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.4, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// COMP-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// COMP-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// COMP-NEXT:    ]
+// COMP:       .omp.reduction.case1:
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointmLERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.case2:
+// COMP-NEXT:    [[TMP28:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4
+// COMP-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointmLERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.default:
+// COMP-NEXT:    br label [[OMP_PRECOND_END]]
+// COMP:       omp.precond.end:
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.4
+// COMP-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// COMP-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// COMP-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// COMP-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// COMP-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// COMP-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointmLERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp_outlined..5
+// COMP-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// COMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// COMP-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// COMP-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// COMP-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// COMP-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// COMP-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// COMP-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 0, i32* [[I]], align 4
+// COMP-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// COMP-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// COMP:       omp.precond.then:
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// COMP-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// COMP-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// COMP-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// COMP-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// COMP:       cond.true:
+// COMP-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    br label [[COND_END:%.*]]
+// COMP:       cond.false:
+// COMP-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    br label [[COND_END]]
+// COMP:       cond.end:
+// COMP-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// COMP-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// COMP:       omp.inner.for.cond:
+// COMP-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// COMP-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// COMP-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// COMP:       omp.inner.for.body:
+// COMP-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// COMP-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// COMP-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// COMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// COMP:       omp.body.continue:
+// COMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// COMP:       omp.inner.for.inc:
+// COMP-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// COMP-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// COMP:       omp.inner.for.end:
+// COMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// COMP:       omp.loop.exit:
+// COMP-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// COMP-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// COMP-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// COMP-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// COMP-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// COMP-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.6, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// COMP-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// COMP-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// COMP-NEXT:    ]
+// COMP:       .omp.reduction.case1:
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaNERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.case2:
+// COMP-NEXT:    [[TMP28:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4
+// COMP-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaNERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.default:
+// COMP-NEXT:    br label [[OMP_PRECOND_END]]
+// COMP:       omp.precond.end:
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.6
+// COMP-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// COMP-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// COMP-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// COMP-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// COMP-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// COMP-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaNERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp_outlined..7
+// COMP-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// COMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// COMP-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// COMP-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// COMP-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// COMP-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// COMP-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// COMP-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 0, i32* [[I]], align 4
+// COMP-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// COMP-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// COMP:       omp.precond.then:
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// COMP-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// COMP-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// COMP-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// COMP-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// COMP:       cond.true:
+// COMP-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    br label [[COND_END:%.*]]
+// COMP:       cond.false:
+// COMP-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    br label [[COND_END]]
+// COMP:       cond.end:
+// COMP-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// COMP-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// COMP:       omp.inner.for.cond:
+// COMP-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// COMP-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// COMP-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// COMP:       omp.inner.for.body:
+// COMP-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// COMP-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// COMP-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// COMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// COMP:       omp.body.continue:
+// COMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// COMP:       omp.inner.for.inc:
+// COMP-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// COMP-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// COMP:       omp.inner.for.end:
+// COMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// COMP:       omp.loop.exit:
+// COMP-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// COMP-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// COMP-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// COMP-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// COMP-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// COMP-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.8, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// COMP-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// COMP-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// COMP-NEXT:    ]
+// COMP:       .omp.reduction.case1:
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointoRERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.case2:
+// COMP-NEXT:    [[TMP28:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4
+// COMP-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointoRERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.default:
+// COMP-NEXT:    br label [[OMP_PRECOND_END]]
+// COMP:       omp.precond.end:
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.8
+// COMP-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// COMP-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// COMP-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// COMP-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// COMP-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// COMP-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointoRERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp_outlined..9
+// COMP-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// COMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// COMP-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// COMP-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// COMP-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// COMP-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// COMP-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// COMP-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 0, i32* [[I]], align 4
+// COMP-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// COMP-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// COMP:       omp.precond.then:
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// COMP-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// COMP-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// COMP-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// COMP-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// COMP:       cond.true:
+// COMP-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    br label [[COND_END:%.*]]
+// COMP:       cond.false:
+// COMP-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    br label [[COND_END]]
+// COMP:       cond.end:
+// COMP-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// COMP-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// COMP:       omp.inner.for.cond:
+// COMP-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// COMP-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// COMP-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// COMP:       omp.inner.for.body:
+// COMP-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// COMP-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// COMP-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// COMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// COMP:       omp.body.continue:
+// COMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// COMP:       omp.inner.for.inc:
+// COMP-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// COMP-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// COMP:       omp.inner.for.end:
+// COMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// COMP:       omp.loop.exit:
+// COMP-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// COMP-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// COMP-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// COMP-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// COMP-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// COMP-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.10, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// COMP-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// COMP-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// COMP-NEXT:    ]
+// COMP:       .omp.reduction.case1:
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointeOERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.case2:
+// COMP-NEXT:    [[TMP28:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4
+// COMP-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointeOERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP29]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.default:
+// COMP-NEXT:    br label [[OMP_PRECOND_END]]
+// COMP:       omp.precond.end:
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.10
+// COMP-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// COMP-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// COMP-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// COMP-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// COMP-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// COMP-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointeOERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp_outlined..11
+// COMP-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// COMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// COMP-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// COMP-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// COMP-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// COMP-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// COMP-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// COMP-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// COMP-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// COMP-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 0, i32* [[I]], align 4
+// COMP-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// COMP-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// COMP:       omp.precond.then:
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// COMP-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// COMP-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// COMP-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// COMP-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// COMP:       cond.true:
+// COMP-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    br label [[COND_END:%.*]]
+// COMP:       cond.false:
+// COMP-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    br label [[COND_END]]
+// COMP:       cond.end:
+// COMP-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// COMP-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// COMP:       omp.inner.for.cond:
+// COMP-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// COMP-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// COMP-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// COMP:       omp.inner.for.body:
+// COMP-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// COMP-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// COMP-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// COMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// COMP:       omp.body.continue:
+// COMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// COMP:       omp.inner.for.inc:
+// COMP-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// COMP-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// COMP:       omp.inner.for.end:
+// COMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// COMP:       omp.loop.exit:
+// COMP-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// COMP-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// COMP-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// COMP-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// COMP-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// COMP-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.12, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// COMP-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// COMP-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// COMP-NEXT:    ]
+// COMP:       .omp.reduction.case1:
+// COMP-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// COMP-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.case2:
+// COMP-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// COMP-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointaaERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// COMP-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// COMP-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// COMP-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.default:
+// COMP-NEXT:    br label [[OMP_PRECOND_END]]
+// COMP:       omp.precond.end:
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.12
+// COMP-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// COMP-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// COMP-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// COMP-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// COMP-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// COMP-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// COMP-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// COMP-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// COMP-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// COMP-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp_outlined..13
+// COMP-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[N:%.*]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED:%.*]], %struct.Point** nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32*, align 8
+// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca %struct.Point**, align 8
+// COMP-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[I:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    [[I4:%.*]] = alloca i32, align 4
+// COMP-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
+// COMP-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
+// COMP-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
+// COMP-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// COMP-NEXT:    store i32* [[N]], i32** [[N_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point* [[RED]], %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    store %struct.Point** [[POINTS]], %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[N_ADDR]], align 8
+// COMP-NEXT:    [[TMP1:%.*]] = load %struct.Point*, %struct.Point** [[RED_ADDR]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load %struct.Point**, %struct.Point*** [[POINTS_ADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+// COMP-NEXT:    store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], 0
+// COMP-NEXT:    [[DIV:%.*]] = udiv i32 [[SUB]], 1
+// COMP-NEXT:    [[SUB2:%.*]] = sub i32 [[DIV]], 1
+// COMP-NEXT:    store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 0, i32* [[I]], align 4
+// COMP-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4
+// COMP-NEXT:    [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
+// COMP-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// COMP:       omp.precond.then:
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// COMP-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// COMP-NEXT:    call void @_ZN5PointC1Ev(%struct.Point* nonnull dereferenceable(8) [[RED3]]) #[[ATTR4]]
+// COMP-NEXT:    [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB1]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// COMP-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
+// COMP-NEXT:    br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// COMP:       cond.true:
+// COMP-NEXT:    [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4
+// COMP-NEXT:    br label [[COND_END:%.*]]
+// COMP:       cond.false:
+// COMP-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    br label [[COND_END]]
+// COMP:       cond.end:
+// COMP-NEXT:    [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
+// COMP-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// COMP-NEXT:    store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// COMP:       omp.inner.for.cond:
+// COMP-NEXT:    [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// COMP-NEXT:    [[ADD:%.*]] = add i32 [[TMP15]], 1
+// COMP-NEXT:    [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
+// COMP-NEXT:    br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// COMP:       omp.inner.for.body:
+// COMP-NEXT:    [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
+// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
+// COMP-NEXT:    store i32 [[ADD7]], i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP17:%.*]] = load i32, i32* [[I4]], align 4
+// COMP-NEXT:    [[TMP18:%.*]] = load %struct.Point*, %struct.Point** [[TMP2]], align 8
+// COMP-NEXT:    call void @_Z4workR5PointiPKS_(%struct.Point* nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], %struct.Point* [[TMP18]])
+// COMP-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// COMP:       omp.body.continue:
+// COMP-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// COMP:       omp.inner.for.inc:
+// COMP-NEXT:    [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
+// COMP-NEXT:    store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
+// COMP-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// COMP:       omp.inner.for.end:
+// COMP-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// COMP:       omp.loop.exit:
+// COMP-NEXT:    [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
+// COMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]])
+// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
+// COMP-NEXT:    [[TMP23:%.*]] = bitcast %struct.Point* [[RED3]] to i8*
+// COMP-NEXT:    store i8* [[TMP23]], i8** [[TMP22]], align 8
+// COMP-NEXT:    [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
+// COMP-NEXT:    [[TMP26:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
+// COMP-NEXT:    [[TMP27:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 1, i64 8, i8* [[TMP26]], void (i8*, i8*)* @.omp.reduction.reduction_func.14, [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    switch i32 [[TMP27]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
+// COMP-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
+// COMP-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
+// COMP-NEXT:    ]
+// COMP:       .omp.reduction.case1:
+// COMP-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    [[TMP28:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// COMP-NEXT:    store i64 [[CALL]], i64* [[TMP28]], align 4
+// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], [8 x i32]* @.gomp_critical_user_.reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.case2:
+// COMP-NEXT:    [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// COMP-NEXT:    [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4
+// COMP-NEXT:    call void @__kmpc_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointooERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[RED3]])
+// COMP-NEXT:    [[TMP31:%.*]] = bitcast %struct.Point* [[REF_TMP10]] to i64*
+// COMP-NEXT:    store i64 [[CALL11]], i64* [[TMP31]], align 4
+// COMP-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP1]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP10]])
+// COMP-NEXT:    call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
+// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
+// COMP:       .omp.reduction.default:
+// COMP-NEXT:    br label [[OMP_PRECOND_END]]
+// COMP:       omp.precond.end:
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.14
+// COMP-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR5]] {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[DOTADDR:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca i8*, align 8
+// COMP-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
+// COMP-NEXT:    store i8* [[TMP0]], i8** [[DOTADDR]], align 8
+// COMP-NEXT:    store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
+// COMP-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
+// COMP-NEXT:    [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
+// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
+// COMP-NEXT:    [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
+// COMP-NEXT:    [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.Point*
+// COMP-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
+// COMP-NEXT:    [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
+// COMP-NEXT:    [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.Point*
+// COMP-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[TMP8]])
+// COMP-NEXT:    [[TMP12:%.*]] = bitcast %struct.Point* [[REF_TMP]] to i64*
+// COMP-NEXT:    store i64 [[CALL]], i64* [[TMP12]], align 4
+// COMP-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) %struct.Point* @_ZN5PointaSERKS_(%struct.Point* nonnull dereferenceable(8) [[TMP11]], %struct.Point* nonnull align 4 dereferenceable(8) [[REF_TMP]])
+// COMP-NEXT:    ret void
+//
+//
+// COMP-LABEL: define {{[^@]+}}@_ZN5PointC2Ev
+// COMP-SAME: (%struct.Point* nonnull dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 {
+// COMP-NEXT:  entry:
+// COMP-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Point*, align 8
+// COMP-NEXT:    store %struct.Point* [[THIS]], %struct.Point** [[THIS_ADDR]], align 8
+// COMP-NEXT:    [[THIS1:%.*]] = load %struct.Point*, %struct.Point** [[THIS_ADDR]], align 8
+// COMP-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_POINT:%.*]], %struct.Point* [[THIS1]], i32 0, i32 0
+// COMP-NEXT:    store i32 0, i32* [[X]], align 4
+// COMP-NEXT:    [[Y:%.*]] = getelementptr inbounds [[STRUCT_POINT]], %struct.Point* [[THIS1]], i32 0, i32 1
+// COMP-NEXT:    store i32 0, i32* [[Y]], align 4
+// COMP-NEXT:    ret void
+//

diff  --git a/clang/test/OpenMP/sections_reduction_messages.cpp b/clang/test/OpenMP/sections_reduction_messages.cpp
index 1ed9b491fc1d1..8fa99dffa5bce 100644
--- a/clang/test/OpenMP/sections_reduction_messages.cpp
+++ b/clang/test/OpenMP/sections_reduction_messages.cpp
@@ -401,7 +401,7 @@ int main(int argc, char **argv) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp sections reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   {
     foo();
   }

diff  --git a/clang/test/OpenMP/simd_reduction_messages.cpp b/clang/test/OpenMP/simd_reduction_messages.cpp
index 17fbc60689818..5a436fc389167 100644
--- a/clang/test/OpenMP/simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/simd_reduction_messages.cpp
@@ -296,7 +296,7 @@ int main(int argc, char **argv) {
 #pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/target_parallel_for_reduction_messages.cpp b/clang/test/OpenMP/target_parallel_for_reduction_messages.cpp
index c1d36650ee63a..09bbb6720e234 100644
--- a/clang/test/OpenMP/target_parallel_for_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_reduction_messages.cpp
@@ -303,7 +303,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
index 199bc57dada02..19b0aab4f9fe7 100644
--- a/clang/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
@@ -305,7 +305,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/target_parallel_reduction_messages.cpp b/clang/test/OpenMP/target_parallel_reduction_messages.cpp
index a4ee11b974f87..82f24359e862c 100644
--- a/clang/test/OpenMP/target_parallel_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_reduction_messages.cpp
@@ -256,7 +256,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
 #pragma omp target parallel reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
   foo();

diff  --git a/clang/test/OpenMP/target_reduction_messages.cpp b/clang/test/OpenMP/target_reduction_messages.cpp
index 699b793706be6..4cf2eb938ed2e 100644
--- a/clang/test/OpenMP/target_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_reduction_messages.cpp
@@ -253,7 +253,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
 #pragma omp target reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
   foo();

diff  --git a/clang/test/OpenMP/target_simd_reduction_messages.cpp b/clang/test/OpenMP/target_simd_reduction_messages.cpp
index fcff164c06fd3..43e0a32e7db2d 100644
--- a/clang/test/OpenMP/target_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_simd_reduction_messages.cpp
@@ -303,7 +303,7 @@ int main(int argc, char **argv) {
 #pragma omp target simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
index cc378410e0003..cfe6b6488a0ba 100644
--- a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
@@ -240,7 +240,7 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target teams distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();

diff  --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
index bb56fd8f392c2..c63a754fe4d55 100644
--- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
@@ -241,7 +241,7 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target teams distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();

diff  --git a/clang/test/OpenMP/target_teams_distribute_reduction_messages.cpp b/clang/test/OpenMP/target_teams_distribute_reduction_messages.cpp
index 5c91b6bbf1b76..af6860080463c 100644
--- a/clang/test/OpenMP/target_teams_distribute_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_reduction_messages.cpp
@@ -245,7 +245,7 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target teams distribute reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();

diff  --git a/clang/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
index 797b6e7fc8cff..1ffc2dd9df4e8 100644
--- a/clang/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
@@ -241,7 +241,7 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target teams distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();

diff  --git a/clang/test/OpenMP/target_teams_reduction_messages.cpp b/clang/test/OpenMP/target_teams_reduction_messages.cpp
index a34652c90afc3..3832ce1d8431e 100644
--- a/clang/test/OpenMP/target_teams_reduction_messages.cpp
+++ b/clang/test/OpenMP/target_teams_reduction_messages.cpp
@@ -256,7 +256,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target teams reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp target teams reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
 #pragma omp target teams reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
   foo();

diff  --git a/clang/test/OpenMP/task_in_reduction_message.cpp b/clang/test/OpenMP/task_in_reduction_message.cpp
index 5b7fc74ae52ee..e71e9f9910dca 100644
--- a/clang/test/OpenMP/task_in_reduction_message.cpp
+++ b/clang/test/OpenMP/task_in_reduction_message.cpp
@@ -287,7 +287,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp task in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
-#pragma omp task in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp task in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
 #pragma omp taskgroup task_reduction(+:k)
 #pragma omp task in_reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/taskgroup_task_reduction_messages.cpp b/clang/test/OpenMP/taskgroup_task_reduction_messages.cpp
index fe7baf4091dd5..5fb141284c994 100644
--- a/clang/test/OpenMP/taskgroup_task_reduction_messages.cpp
+++ b/clang/test/OpenMP/taskgroup_task_reduction_messages.cpp
@@ -228,7 +228,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp taskgroup task_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
-#pragma omp taskgroup task_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp taskgroup task_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
 #pragma omp taskgroup task_reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
   foo();

diff  --git a/clang/test/OpenMP/taskloop_in_reduction_messages.cpp b/clang/test/OpenMP/taskloop_in_reduction_messages.cpp
index a87d3f0b99bb6..b910d592ab976 100644
--- a/clang/test/OpenMP/taskloop_in_reduction_messages.cpp
+++ b/clang/test/OpenMP/taskloop_in_reduction_messages.cpp
@@ -344,7 +344,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp taskloop in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:k)

diff  --git a/clang/test/OpenMP/taskloop_reduction_messages.cpp b/clang/test/OpenMP/taskloop_reduction_messages.cpp
index b38a6f31dfc99..0f42d0b49dbda 100644
--- a/clang/test/OpenMP/taskloop_reduction_messages.cpp
+++ b/clang/test/OpenMP/taskloop_reduction_messages.cpp
@@ -312,7 +312,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp taskloop reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/taskloop_simd_in_reduction_messages.cpp b/clang/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
index 7003c24aba859..ff6f919ba61b4 100644
--- a/clang/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
+++ b/clang/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
@@ -344,7 +344,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop simd in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp taskloop simd in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:k)

diff  --git a/clang/test/OpenMP/taskloop_simd_reduction_messages.cpp b/clang/test/OpenMP/taskloop_simd_reduction_messages.cpp
index ab415790ca8c1..766d1115f8e68 100644
--- a/clang/test/OpenMP/taskloop_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/taskloop_simd_reduction_messages.cpp
@@ -312,7 +312,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp taskloop simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
index 7efdf179d3653..0fe1d401ef312 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
@@ -284,7 +284,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp teams distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
index b6a3a30baaed7..3333298e24822 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
@@ -284,7 +284,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp teams distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/teams_distribute_reduction_messages.cpp b/clang/test/OpenMP/teams_distribute_reduction_messages.cpp
index fb793e0008ad6..56e01e15c66f8 100644
--- a/clang/test/OpenMP/teams_distribute_reduction_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_reduction_messages.cpp
@@ -290,7 +290,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp teams distribute reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/teams_distribute_simd_reduction_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
index a167e9c10f2f1..9709a30cbf63d 100644
--- a/clang/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
@@ -284,7 +284,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp teams distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}

diff  --git a/clang/test/OpenMP/teams_reduction_messages.cpp b/clang/test/OpenMP/teams_reduction_messages.cpp
index 674d1ca85c8ce..aee72d9e53249 100644
--- a/clang/test/OpenMP/teams_reduction_messages.cpp
+++ b/clang/test/OpenMP/teams_reduction_messages.cpp
@@ -303,7 +303,7 @@ int main(int argc, char **argv) {
 #pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+#pragma omp teams reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
 #pragma omp target
 #pragma omp teams reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}


        


More information about the cfe-commits mailing list