llvm/clang/test/OpenMP/reduction_compound_op.cpp

// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
//  RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp -DNORM \
//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix NORM

//RUN: %clang_cc1 -no-enable-noundef-analysis -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 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp -DNORM -DCOMP \
//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix COMP

//RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp-simd -DNORM \
//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix SIMD-ONLY

//RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp-simd -DCOMP \
//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix SIMD-ONLY

//RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp-simd -DNORM -DCOMP \
//RUN:  -emit-llvm -o - %s | FileCheck %s --check-prefix SIMD-ONLY


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:%.*]], ptr [[POINTS:%.*]]) #[[ATTR0:[0-9]+]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[RED:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// NORM-NEXT:    store i32 [[N]], ptr [[N_ADDR]], align 4
// NORM-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED]]) #[[ATTR2:[0-9]+]]
// NORM-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// NORM-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.1, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// NORM-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.2, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// NORM-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.3, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// NORM-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.4, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// NORM-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.5, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// NORM-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.6, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// NORM-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.7, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_ZN5PointC1Ev
// NORM-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
// NORM-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
// NORM-NEXT:    call void @_ZN5PointC2Ev(ptr nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR2]]
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined
// NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1:[0-9]+]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// NORM-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// NORM-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// NORM-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// NORM-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// NORM-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 0, ptr [[I]], align 4
// NORM-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// NORM-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// NORM-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1:[0-9]+]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// NORM-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    br label [[COND_END:%.*]]
// NORM:       cond.false:
// NORM-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// NORM:       omp.inner.for.cond:
// NORM-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// NORM-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// NORM-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// NORM-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// NORM-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// NORM-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// NORM-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// NORM-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// NORM-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2:[0-9]+]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// NORM:       .omp.reduction.case2:
// NORM-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// NORM-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// NORM-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.omp.reduction.reduction_func
// NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4:[0-9]+]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// NORM-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// NORM-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// NORM-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.1
// NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// NORM-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// NORM-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// NORM-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// NORM-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// NORM-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 0, ptr [[I]], align 4
// NORM-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// NORM-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// NORM-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// NORM-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    br label [[COND_END:%.*]]
// NORM:       cond.false:
// NORM-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// NORM:       omp.inner.for.cond:
// NORM-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// NORM-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// NORM-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// NORM-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// NORM-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// NORM-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// NORM-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// NORM-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// NORM-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.1.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// NORM:       .omp.reduction.case2:
// NORM-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// NORM-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// NORM-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.1.omp.reduction.reduction_func
// NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// NORM-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// NORM-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// NORM-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.2
// NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// NORM-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// NORM-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// NORM-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// NORM-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// NORM-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 0, ptr [[I]], align 4
// NORM-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// NORM-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// NORM-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// NORM-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    br label [[COND_END:%.*]]
// NORM:       cond.false:
// NORM-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// NORM:       omp.inner.for.cond:
// NORM-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// NORM-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// NORM-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// NORM-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// NORM-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// NORM-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// NORM-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// NORM-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// NORM-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.2.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// NORM:       .omp.reduction.case2:
// NORM-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// NORM-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointmlERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// NORM-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.2.omp.reduction.reduction_func
// NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// NORM-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// NORM-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// NORM-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointmlERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.3
// NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// NORM-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// NORM-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// NORM-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// NORM-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// NORM-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 0, ptr [[I]], align 4
// NORM-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// NORM-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// NORM-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// NORM-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    br label [[COND_END:%.*]]
// NORM:       cond.false:
// NORM-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// NORM:       omp.inner.for.cond:
// NORM-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// NORM-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// NORM-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// NORM-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// NORM-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// NORM-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// NORM-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// NORM-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// NORM-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.3.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// NORM:       .omp.reduction.case2:
// NORM-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// NORM-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointanERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// NORM-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.3.omp.reduction.reduction_func
// NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// NORM-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// NORM-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// NORM-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointanERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.4
// NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// NORM-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// NORM-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// NORM-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// NORM-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// NORM-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 0, ptr [[I]], align 4
// NORM-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// NORM-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// NORM-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// NORM-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    br label [[COND_END:%.*]]
// NORM:       cond.false:
// NORM-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// NORM:       omp.inner.for.cond:
// NORM-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// NORM-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// NORM-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// NORM-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// NORM-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// NORM-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// NORM-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// NORM-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// NORM-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.4.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// NORM:       .omp.reduction.case2:
// NORM-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// NORM-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointorERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// NORM-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.4.omp.reduction.reduction_func
// NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// NORM-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// NORM-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// NORM-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointorERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.5
// NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// NORM-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// NORM-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// NORM-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// NORM-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// NORM-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 0, ptr [[I]], align 4
// NORM-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// NORM-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// NORM-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// NORM-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    br label [[COND_END:%.*]]
// NORM:       cond.false:
// NORM-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// NORM:       omp.inner.for.cond:
// NORM-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// NORM-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// NORM-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// NORM-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// NORM-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// NORM-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// NORM-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// NORM-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// NORM-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.5.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// NORM:       .omp.reduction.case2:
// NORM-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// NORM-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointeoERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// NORM-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.5.omp.reduction.reduction_func
// NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// NORM-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// NORM-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// NORM-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointeoERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.6
// NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// NORM-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// NORM-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// NORM-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// NORM-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// NORM-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 0, ptr [[I]], align 4
// NORM-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// NORM-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// NORM-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// NORM-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    br label [[COND_END:%.*]]
// NORM:       cond.false:
// NORM-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// NORM:       omp.inner.for.cond:
// NORM-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// NORM-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// NORM-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// NORM-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// NORM-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// NORM-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// NORM-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// NORM-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// NORM-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.6.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// NORM:       .omp.reduction.case2:
// NORM-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// NORM-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// NORM-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.6.omp.reduction.reduction_func
// NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// NORM-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// NORM-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// NORM-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.7
// NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// NORM-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// NORM-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// NORM-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// NORM-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// NORM-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// NORM-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// NORM-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 0, ptr [[I]], align 4
// NORM-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// NORM-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// NORM-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// NORM-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// NORM-NEXT:    br label [[COND_END:%.*]]
// NORM:       cond.false:
// NORM-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// NORM-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// NORM-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// NORM:       omp.inner.for.cond:
// NORM-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// NORM-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// NORM-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// NORM-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// NORM-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// NORM-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// NORM-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// NORM-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// NORM-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// NORM-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// NORM-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// NORM-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// NORM-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.7.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// NORM-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// NORM:       .omp.reduction.case2:
// NORM-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// NORM-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// NORM-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// NORM-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// NORM-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// NORM-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// NORM-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.7.omp.reduction.reduction_func
// NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// NORM-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// NORM-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// NORM-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// NORM-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// NORM-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// NORM-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// NORM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// NORM-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// NORM-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// NORM-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// NORM-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// NORM-NEXT:    ret void
//
//
// NORM-LABEL: define {{[^@]+}}@_ZN5PointC2Ev
// NORM-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
// NORM-NEXT:  entry:
// NORM-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
// NORM-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
// NORM-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
// NORM-NEXT:    [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_POINT:%.*]], ptr [[THIS1]], i32 0, i32 0
// NORM-NEXT:    store i32 0, ptr [[X]], align 4
// NORM-NEXT:    [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_POINT]], ptr [[THIS1]], i32 0, i32 1
// NORM-NEXT:    store i32 0, ptr [[Y]], align 4
// NORM-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point
// COMP-SAME: (i32 [[N:%.*]], ptr [[POINTS:%.*]]) #[[ATTR0:[0-9]+]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[RED:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// COMP-NEXT:    store i32 [[N]], ptr [[N_ADDR]], align 4
// COMP-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED]]) #[[ATTR2:[0-9]+]]
// COMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// COMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.1, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// COMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.2, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// COMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.3, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// COMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.4, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// COMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.5, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// COMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.6, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// COMP-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.7, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_ZN5PointC1Ev
// COMP-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
// COMP-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
// COMP-NEXT:    call void @_ZN5PointC2Ev(ptr nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR2]]
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined
// COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1:[0-9]+]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// COMP-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// COMP-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// COMP-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// COMP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// COMP-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// COMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 0, ptr [[I]], align 4
// COMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// COMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// COMP-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1:[0-9]+]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// COMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    br label [[COND_END:%.*]]
// COMP:       cond.false:
// COMP-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// COMP:       omp.inner.for.cond:
// COMP-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// COMP-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// COMP-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// COMP-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// COMP-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// COMP-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// COMP-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// COMP-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// COMP-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2:[0-9]+]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    switch i32 [[TMP25]], 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) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// COMP:       .omp.reduction.case2:
// COMP-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// COMP-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.omp.reduction.reduction_func
// COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4:[0-9]+]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// COMP-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// COMP-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// COMP-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.1
// COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// COMP-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// COMP-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// COMP-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// COMP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// COMP-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// COMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 0, ptr [[I]], align 4
// COMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// COMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// COMP-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// COMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    br label [[COND_END:%.*]]
// COMP:       cond.false:
// COMP-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// COMP:       omp.inner.for.cond:
// COMP-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// COMP-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// COMP-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// COMP-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// COMP-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// COMP-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// COMP-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// COMP-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// COMP-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.1.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    switch i32 [[TMP25]], 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) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// COMP:       .omp.reduction.case2:
// COMP-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// COMP-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.1.omp.reduction.reduction_func
// COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// COMP-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// COMP-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// COMP-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.2
// COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// COMP-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// COMP-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// COMP-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// COMP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// COMP-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// COMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 0, ptr [[I]], align 4
// COMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// COMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// COMP-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// COMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    br label [[COND_END:%.*]]
// COMP:       cond.false:
// COMP-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// COMP:       omp.inner.for.cond:
// COMP-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// COMP-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// COMP-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// COMP-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// COMP-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// COMP-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// COMP-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// COMP-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// COMP-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.2.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    switch i32 [[TMP25]], 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) ptr @_ZN5PointmLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// COMP:       .omp.reduction.case2:
// COMP-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// COMP-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointmLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.2.omp.reduction.reduction_func
// COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// COMP-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// COMP-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// COMP-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointmLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.3
// COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// COMP-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// COMP-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// COMP-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// COMP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// COMP-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// COMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 0, ptr [[I]], align 4
// COMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// COMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// COMP-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// COMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    br label [[COND_END:%.*]]
// COMP:       cond.false:
// COMP-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// COMP:       omp.inner.for.cond:
// COMP-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// COMP-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// COMP-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// COMP-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// COMP-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// COMP-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// COMP-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// COMP-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// COMP-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.3.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    switch i32 [[TMP25]], 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) ptr @_ZN5PointaNERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// COMP:       .omp.reduction.case2:
// COMP-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// COMP-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaNERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.3.omp.reduction.reduction_func
// COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// COMP-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// COMP-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// COMP-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaNERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.4
// COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// COMP-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// COMP-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// COMP-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// COMP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// COMP-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// COMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 0, ptr [[I]], align 4
// COMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// COMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// COMP-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// COMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    br label [[COND_END:%.*]]
// COMP:       cond.false:
// COMP-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// COMP:       omp.inner.for.cond:
// COMP-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// COMP-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// COMP-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// COMP-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// COMP-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// COMP-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// COMP-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// COMP-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// COMP-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.4.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    switch i32 [[TMP25]], 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) ptr @_ZN5PointoRERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// COMP:       .omp.reduction.case2:
// COMP-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// COMP-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointoRERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.4.omp.reduction.reduction_func
// COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// COMP-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// COMP-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// COMP-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointoRERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.5
// COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// COMP-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// COMP-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// COMP-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// COMP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// COMP-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// COMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 0, ptr [[I]], align 4
// COMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// COMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// COMP-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// COMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    br label [[COND_END:%.*]]
// COMP:       cond.false:
// COMP-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// COMP:       omp.inner.for.cond:
// COMP-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// COMP-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// COMP-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// COMP-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// COMP-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// COMP-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// COMP-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// COMP-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// COMP-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.5.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    switch i32 [[TMP25]], 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) ptr @_ZN5PointeOERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// COMP:       .omp.reduction.case2:
// COMP-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// COMP-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointeOERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.5.omp.reduction.reduction_func
// COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// COMP-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// COMP-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// COMP-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// COMP-NEXT:    [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointeOERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.6
// COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// COMP-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// COMP-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// COMP-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// COMP-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// COMP-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// COMP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// COMP-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// COMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 0, ptr [[I]], align 4
// COMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// COMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// COMP-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// COMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    br label [[COND_END:%.*]]
// COMP:       cond.false:
// COMP-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// COMP:       omp.inner.for.cond:
// COMP-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// COMP-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// COMP-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// COMP-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// COMP-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// COMP-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// COMP-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// COMP-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// COMP-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.6.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// COMP:       .omp.reduction.case2:
// COMP-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// COMP-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// COMP-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// COMP-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// COMP-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.6.omp.reduction.reduction_func
// COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// COMP-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// COMP-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// COMP-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// COMP-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// COMP-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// COMP-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.7
// COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR1]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[N_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[RED_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, 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 ptr], align 8
// COMP-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
// COMP-NEXT:    [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
// COMP-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
// COMP-NEXT:    store ptr [[N]], ptr [[N_ADDR]], align 8
// COMP-NEXT:    store ptr [[RED]], ptr [[RED_ADDR]], align 8
// COMP-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
// COMP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
// COMP-NEXT:    store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
// COMP-NEXT:    [[TMP4:%.*]] = load i32, ptr [[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]], ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 0, ptr [[I]], align 4
// COMP-NEXT:    [[TMP5:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
// COMP-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
// COMP-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR2]]
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
// COMP-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP10:%.*]] = load i32, ptr [[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, ptr [[DOTCAPTURE_EXPR_1]], align 4
// COMP-NEXT:    br label [[COND_END:%.*]]
// COMP:       cond.false:
// COMP-NEXT:    [[TMP12:%.*]] = load i32, ptr [[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]], ptr [[DOTOMP_UB]], align 4
// COMP-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
// COMP-NEXT:    store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
// COMP:       omp.inner.for.cond:
// COMP-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[TMP15:%.*]] = load i32, ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[MUL:%.*]] = mul i32 [[TMP16]], 1
// COMP-NEXT:    [[ADD7:%.*]] = add i32 0, [[MUL]]
// COMP-NEXT:    store i32 [[ADD7]], ptr [[I4]], align 4
// COMP-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
// COMP-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
// COMP-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[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, ptr [[DOTOMP_IV]], align 4
// COMP-NEXT:    [[ADD8:%.*]] = add i32 [[TMP19]], 1
// COMP-NEXT:    store i32 [[ADD8]], ptr [[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 ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
// COMP-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
// COMP-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// COMP-NEXT:    store ptr [[RED3]], ptr [[TMP22]], align 8
// COMP-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
// COMP-NEXT:    [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.7.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    switch i32 [[TMP25]], 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_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// COMP-NEXT:    [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// COMP-NEXT:    call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
// COMP-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
// COMP:       .omp.reduction.case2:
// COMP-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
// COMP-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
// COMP-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
// COMP-NEXT:    [[CALL11:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
// COMP-NEXT:    store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
// COMP-NEXT:    [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
// COMP-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.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 {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.7.omp.reduction.reduction_func
// COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR4]] {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[DOTADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[DOTADDR1:%.*]] = alloca ptr, align 8
// COMP-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// COMP-NEXT:    store ptr [[TMP0]], ptr [[DOTADDR]], align 8
// COMP-NEXT:    store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
// COMP-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
// COMP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
// COMP-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
// COMP-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
// COMP-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
// COMP-NEXT:    [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
// COMP-NEXT:    store i64 [[CALL]], ptr [[REF_TMP]], align 4
// COMP-NEXT:    [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
// COMP-NEXT:    ret void
//
//
// COMP-LABEL: define {{[^@]+}}@_ZN5PointC2Ev
// COMP-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
// COMP-NEXT:  entry:
// COMP-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
// COMP-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
// COMP-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
// COMP-NEXT:    [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_POINT:%.*]], ptr [[THIS1]], i32 0, i32 0
// COMP-NEXT:    store i32 0, ptr [[X]], align 4
// COMP-NEXT:    [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_POINT]], ptr [[THIS1]], i32 0, i32 1
// COMP-NEXT:    store i32 0, ptr [[Y]], align 4
// COMP-NEXT:    ret void
//
//
// SIMD-ONLY-LABEL: define {{[^@]+}}@_Z3fooiPK5Point
// SIMD-ONLY-SAME: (i32 [[N:%.*]], ptr [[POINTS:%.*]]) #[[ATTR0:[0-9]+]] {
// SIMD-ONLY-NEXT:  entry:
// SIMD-ONLY-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
// SIMD-ONLY-NEXT:    [[POINTS_ADDR:%.*]] = alloca ptr, align 8
// SIMD-ONLY-NEXT:    [[RED:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
// SIMD-ONLY-NEXT:    [[I:%.*]] = alloca i32, align 4
// SIMD-ONLY-NEXT:    [[I1:%.*]] = alloca i32, align 4
// SIMD-ONLY-NEXT:    [[I8:%.*]] = alloca i32, align 4
// SIMD-ONLY-NEXT:    [[I15:%.*]] = alloca i32, align 4
// SIMD-ONLY-NEXT:    [[I22:%.*]] = alloca i32, align 4
// SIMD-ONLY-NEXT:    [[I29:%.*]] = alloca i32, align 4
// SIMD-ONLY-NEXT:    [[I36:%.*]] = alloca i32, align 4
// SIMD-ONLY-NEXT:    [[I43:%.*]] = alloca i32, align 4
// SIMD-ONLY-NEXT:    store i32 [[N]], ptr [[N_ADDR]], align 4
// SIMD-ONLY-NEXT:    store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED]]) #[[ATTR2:[0-9]+]]
// SIMD-ONLY-NEXT:    store i32 0, ptr [[I]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND:%.*]]
// SIMD-ONLY:       for.cond:
// SIMD-ONLY-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4
// SIMD-ONLY-NEXT:    [[TMP1:%.*]] = load i32, ptr [[N_ADDR]], align 4
// SIMD-ONLY-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP0]], [[TMP1]]
// SIMD-ONLY-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
// SIMD-ONLY:       for.body:
// SIMD-ONLY-NEXT:    [[TMP2:%.*]] = load i32, ptr [[I]], align 4
// SIMD-ONLY-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP2]], ptr [[TMP3]])
// SIMD-ONLY-NEXT:    br label [[FOR_INC:%.*]]
// SIMD-ONLY:       for.inc:
// SIMD-ONLY-NEXT:    [[TMP4:%.*]] = load i32, ptr [[I]], align 4
// SIMD-ONLY-NEXT:    [[INC:%.*]] = add i32 [[TMP4]], 1
// SIMD-ONLY-NEXT:    store i32 [[INC]], ptr [[I]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
// SIMD-ONLY:       for.end:
// SIMD-ONLY-NEXT:    store i32 0, ptr [[I1]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND2:%.*]]
// SIMD-ONLY:       for.cond2:
// SIMD-ONLY-NEXT:    [[TMP5:%.*]] = load i32, ptr [[I1]], align 4
// SIMD-ONLY-NEXT:    [[TMP6:%.*]] = load i32, ptr [[N_ADDR]], align 4
// SIMD-ONLY-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[TMP5]], [[TMP6]]
// SIMD-ONLY-NEXT:    br i1 [[CMP3]], label [[FOR_BODY4:%.*]], label [[FOR_END7:%.*]]
// SIMD-ONLY:       for.body4:
// SIMD-ONLY-NEXT:    [[TMP7:%.*]] = load i32, ptr [[I1]], align 4
// SIMD-ONLY-NEXT:    [[TMP8:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP7]], ptr [[TMP8]])
// SIMD-ONLY-NEXT:    br label [[FOR_INC5:%.*]]
// SIMD-ONLY:       for.inc5:
// SIMD-ONLY-NEXT:    [[TMP9:%.*]] = load i32, ptr [[I1]], align 4
// SIMD-ONLY-NEXT:    [[INC6:%.*]] = add i32 [[TMP9]], 1
// SIMD-ONLY-NEXT:    store i32 [[INC6]], ptr [[I1]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND2]], !llvm.loop [[LOOP4:![0-9]+]]
// SIMD-ONLY:       for.end7:
// SIMD-ONLY-NEXT:    store i32 0, ptr [[I8]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND9:%.*]]
// SIMD-ONLY:       for.cond9:
// SIMD-ONLY-NEXT:    [[TMP10:%.*]] = load i32, ptr [[I8]], align 4
// SIMD-ONLY-NEXT:    [[TMP11:%.*]] = load i32, ptr [[N_ADDR]], align 4
// SIMD-ONLY-NEXT:    [[CMP10:%.*]] = icmp ult i32 [[TMP10]], [[TMP11]]
// SIMD-ONLY-NEXT:    br i1 [[CMP10]], label [[FOR_BODY11:%.*]], label [[FOR_END14:%.*]]
// SIMD-ONLY:       for.body11:
// SIMD-ONLY-NEXT:    [[TMP12:%.*]] = load i32, ptr [[I8]], align 4
// SIMD-ONLY-NEXT:    [[TMP13:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP12]], ptr [[TMP13]])
// SIMD-ONLY-NEXT:    br label [[FOR_INC12:%.*]]
// SIMD-ONLY:       for.inc12:
// SIMD-ONLY-NEXT:    [[TMP14:%.*]] = load i32, ptr [[I8]], align 4
// SIMD-ONLY-NEXT:    [[INC13:%.*]] = add i32 [[TMP14]], 1
// SIMD-ONLY-NEXT:    store i32 [[INC13]], ptr [[I8]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND9]], !llvm.loop [[LOOP5:![0-9]+]]
// SIMD-ONLY:       for.end14:
// SIMD-ONLY-NEXT:    store i32 0, ptr [[I15]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND16:%.*]]
// SIMD-ONLY:       for.cond16:
// SIMD-ONLY-NEXT:    [[TMP15:%.*]] = load i32, ptr [[I15]], align 4
// SIMD-ONLY-NEXT:    [[TMP16:%.*]] = load i32, ptr [[N_ADDR]], align 4
// SIMD-ONLY-NEXT:    [[CMP17:%.*]] = icmp ult i32 [[TMP15]], [[TMP16]]
// SIMD-ONLY-NEXT:    br i1 [[CMP17]], label [[FOR_BODY18:%.*]], label [[FOR_END21:%.*]]
// SIMD-ONLY:       for.body18:
// SIMD-ONLY-NEXT:    [[TMP17:%.*]] = load i32, ptr [[I15]], align 4
// SIMD-ONLY-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP17]], ptr [[TMP18]])
// SIMD-ONLY-NEXT:    br label [[FOR_INC19:%.*]]
// SIMD-ONLY:       for.inc19:
// SIMD-ONLY-NEXT:    [[TMP19:%.*]] = load i32, ptr [[I15]], align 4
// SIMD-ONLY-NEXT:    [[INC20:%.*]] = add i32 [[TMP19]], 1
// SIMD-ONLY-NEXT:    store i32 [[INC20]], ptr [[I15]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND16]], !llvm.loop [[LOOP6:![0-9]+]]
// SIMD-ONLY:       for.end21:
// SIMD-ONLY-NEXT:    store i32 0, ptr [[I22]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND23:%.*]]
// SIMD-ONLY:       for.cond23:
// SIMD-ONLY-NEXT:    [[TMP20:%.*]] = load i32, ptr [[I22]], align 4
// SIMD-ONLY-NEXT:    [[TMP21:%.*]] = load i32, ptr [[N_ADDR]], align 4
// SIMD-ONLY-NEXT:    [[CMP24:%.*]] = icmp ult i32 [[TMP20]], [[TMP21]]
// SIMD-ONLY-NEXT:    br i1 [[CMP24]], label [[FOR_BODY25:%.*]], label [[FOR_END28:%.*]]
// SIMD-ONLY:       for.body25:
// SIMD-ONLY-NEXT:    [[TMP22:%.*]] = load i32, ptr [[I22]], align 4
// SIMD-ONLY-NEXT:    [[TMP23:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP22]], ptr [[TMP23]])
// SIMD-ONLY-NEXT:    br label [[FOR_INC26:%.*]]
// SIMD-ONLY:       for.inc26:
// SIMD-ONLY-NEXT:    [[TMP24:%.*]] = load i32, ptr [[I22]], align 4
// SIMD-ONLY-NEXT:    [[INC27:%.*]] = add i32 [[TMP24]], 1
// SIMD-ONLY-NEXT:    store i32 [[INC27]], ptr [[I22]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND23]], !llvm.loop [[LOOP7:![0-9]+]]
// SIMD-ONLY:       for.end28:
// SIMD-ONLY-NEXT:    store i32 0, ptr [[I29]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND30:%.*]]
// SIMD-ONLY:       for.cond30:
// SIMD-ONLY-NEXT:    [[TMP25:%.*]] = load i32, ptr [[I29]], align 4
// SIMD-ONLY-NEXT:    [[TMP26:%.*]] = load i32, ptr [[N_ADDR]], align 4
// SIMD-ONLY-NEXT:    [[CMP31:%.*]] = icmp ult i32 [[TMP25]], [[TMP26]]
// SIMD-ONLY-NEXT:    br i1 [[CMP31]], label [[FOR_BODY32:%.*]], label [[FOR_END35:%.*]]
// SIMD-ONLY:       for.body32:
// SIMD-ONLY-NEXT:    [[TMP27:%.*]] = load i32, ptr [[I29]], align 4
// SIMD-ONLY-NEXT:    [[TMP28:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP27]], ptr [[TMP28]])
// SIMD-ONLY-NEXT:    br label [[FOR_INC33:%.*]]
// SIMD-ONLY:       for.inc33:
// SIMD-ONLY-NEXT:    [[TMP29:%.*]] = load i32, ptr [[I29]], align 4
// SIMD-ONLY-NEXT:    [[INC34:%.*]] = add i32 [[TMP29]], 1
// SIMD-ONLY-NEXT:    store i32 [[INC34]], ptr [[I29]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND30]], !llvm.loop [[LOOP8:![0-9]+]]
// SIMD-ONLY:       for.end35:
// SIMD-ONLY-NEXT:    store i32 0, ptr [[I36]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND37:%.*]]
// SIMD-ONLY:       for.cond37:
// SIMD-ONLY-NEXT:    [[TMP30:%.*]] = load i32, ptr [[I36]], align 4
// SIMD-ONLY-NEXT:    [[TMP31:%.*]] = load i32, ptr [[N_ADDR]], align 4
// SIMD-ONLY-NEXT:    [[CMP38:%.*]] = icmp ult i32 [[TMP30]], [[TMP31]]
// SIMD-ONLY-NEXT:    br i1 [[CMP38]], label [[FOR_BODY39:%.*]], label [[FOR_END42:%.*]]
// SIMD-ONLY:       for.body39:
// SIMD-ONLY-NEXT:    [[TMP32:%.*]] = load i32, ptr [[I36]], align 4
// SIMD-ONLY-NEXT:    [[TMP33:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP32]], ptr [[TMP33]])
// SIMD-ONLY-NEXT:    br label [[FOR_INC40:%.*]]
// SIMD-ONLY:       for.inc40:
// SIMD-ONLY-NEXT:    [[TMP34:%.*]] = load i32, ptr [[I36]], align 4
// SIMD-ONLY-NEXT:    [[INC41:%.*]] = add i32 [[TMP34]], 1
// SIMD-ONLY-NEXT:    store i32 [[INC41]], ptr [[I36]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND37]], !llvm.loop [[LOOP9:![0-9]+]]
// SIMD-ONLY:       for.end42:
// SIMD-ONLY-NEXT:    store i32 0, ptr [[I43]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND44:%.*]]
// SIMD-ONLY:       for.cond44:
// SIMD-ONLY-NEXT:    [[TMP35:%.*]] = load i32, ptr [[I43]], align 4
// SIMD-ONLY-NEXT:    [[TMP36:%.*]] = load i32, ptr [[N_ADDR]], align 4
// SIMD-ONLY-NEXT:    [[CMP45:%.*]] = icmp ult i32 [[TMP35]], [[TMP36]]
// SIMD-ONLY-NEXT:    br i1 [[CMP45]], label [[FOR_BODY46:%.*]], label [[FOR_END49:%.*]]
// SIMD-ONLY:       for.body46:
// SIMD-ONLY-NEXT:    [[TMP37:%.*]] = load i32, ptr [[I43]], align 4
// SIMD-ONLY-NEXT:    [[TMP38:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP37]], ptr [[TMP38]])
// SIMD-ONLY-NEXT:    br label [[FOR_INC47:%.*]]
// SIMD-ONLY:       for.inc47:
// SIMD-ONLY-NEXT:    [[TMP39:%.*]] = load i32, ptr [[I43]], align 4
// SIMD-ONLY-NEXT:    [[INC48:%.*]] = add i32 [[TMP39]], 1
// SIMD-ONLY-NEXT:    store i32 [[INC48]], ptr [[I43]], align 4
// SIMD-ONLY-NEXT:    br label [[FOR_COND44]], !llvm.loop [[LOOP10:![0-9]+]]
// SIMD-ONLY:       for.end49:
// SIMD-ONLY-NEXT:    ret void
//
//
// SIMD-ONLY-LABEL: define {{[^@]+}}@_ZN5PointC1Ev
// SIMD-ONLY-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
// SIMD-ONLY-NEXT:  entry:
// SIMD-ONLY-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
// SIMD-ONLY-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
// SIMD-ONLY-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
// SIMD-ONLY-NEXT:    call void @_ZN5PointC2Ev(ptr nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR2]]
// SIMD-ONLY-NEXT:    ret void
//
//
// SIMD-ONLY-LABEL: define {{[^@]+}}@_ZN5PointC2Ev
// SIMD-ONLY-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
// SIMD-ONLY-NEXT:  entry:
// SIMD-ONLY-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
// SIMD-ONLY-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
// SIMD-ONLY-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
// SIMD-ONLY-NEXT:    [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_POINT:%.*]], ptr [[THIS1]], i32 0, i32 0
// SIMD-ONLY-NEXT:    store i32 0, ptr [[X]], align 4
// SIMD-ONLY-NEXT:    [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_POINT]], ptr [[THIS1]], i32 0, i32 1
// SIMD-ONLY-NEXT:    store i32 0, ptr [[Y]], align 4
// SIMD-ONLY-NEXT:    ret void
//