205 lines · c
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_ size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _2// RUN: %clang_cc1 -fopenmp-enable-irbuilder -verify -fopenmp -x c -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s3// expected-no-diagnostics4 5#ifndef HEADER6#define HEADER7 8 9void unroll_partial_heuristic_for(int n, float *a, float *b, float *c, float *d) {10#pragma omp for11#pragma omp unroll partial(13)12 for (int i = 0; i < n; i++) {13 a[i] = b[i] * c[i] * d[i];14 }15}16 17#endif // HEADER18 19 20 21 22 23// CHECK-LABEL: define {{[^@]+}}@unroll_partial_heuristic_for24// CHECK-SAME: (i32 noundef [[N:%.*]], ptr noundef [[A:%.*]], ptr noundef [[B:%.*]], ptr noundef [[C:%.*]], ptr noundef [[D:%.*]]) #[[ATTR0:[0-9]+]] {25// CHECK-NEXT: entry:26// CHECK-NEXT: [[N_ADDR:%.*]] = alloca i32, align 427// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 828// CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 829// CHECK-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 830// CHECK-NEXT: [[D_ADDR:%.*]] = alloca ptr, align 831// CHECK-NEXT: [[I:%.*]] = alloca i32, align 432// CHECK-NEXT: [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON:%.*]], align 833// CHECK-NEXT: [[AGG_CAPTURED1:%.*]] = alloca [[STRUCT_ANON_0:%.*]], align 434// CHECK-NEXT: [[DOTCOUNT_ADDR:%.*]] = alloca i32, align 435// CHECK-NEXT: [[P_LASTITER:%.*]] = alloca i32, align 436// CHECK-NEXT: [[P_LOWERBOUND:%.*]] = alloca i32, align 437// CHECK-NEXT: [[P_UPPERBOUND:%.*]] = alloca i32, align 438// CHECK-NEXT: [[P_STRIDE:%.*]] = alloca i32, align 439// CHECK-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 440// CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 841// CHECK-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 842// CHECK-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 843// CHECK-NEXT: store ptr [[D]], ptr [[D_ADDR]], align 844// CHECK-NEXT: store i32 0, ptr [[I]], align 445// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[AGG_CAPTURED]], i32 0, i32 046// CHECK-NEXT: store ptr [[I]], ptr [[TMP0]], align 847// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[AGG_CAPTURED]], i32 0, i32 148// CHECK-NEXT: store ptr [[N_ADDR]], ptr [[TMP1]], align 849// CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0]], ptr [[AGG_CAPTURED1]], i32 0, i32 050// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[I]], align 451// CHECK-NEXT: store i32 [[TMP3]], ptr [[TMP2]], align 452// CHECK-NEXT: call void @__captured_stmt(ptr [[DOTCOUNT_ADDR]], ptr [[AGG_CAPTURED]])53// CHECK-NEXT: [[DOTCOUNT:%.*]] = load i32, ptr [[DOTCOUNT_ADDR]], align 454// CHECK-NEXT: br label [[OMP_LOOP_PREHEADER:%.*]]55// CHECK: omp_loop.preheader:56// CHECK-NEXT: [[TMP4:%.*]] = udiv i32 [[DOTCOUNT]], 1357// CHECK-NEXT: [[TMP5:%.*]] = urem i32 [[DOTCOUNT]], 1358// CHECK-NEXT: [[TMP6:%.*]] = icmp ne i32 [[TMP5]], 059// CHECK-NEXT: [[TMP7:%.*]] = zext i1 [[TMP6]] to i3260// CHECK-NEXT: [[OMP_FLOOR0_TRIPCOUNT:%.*]] = add nuw i32 [[TMP4]], [[TMP7]]61// CHECK-NEXT: br label [[OMP_FLOOR0_PREHEADER:%.*]]62// CHECK: omp_floor0.preheader:63// CHECK-NEXT: store i32 0, ptr [[P_LOWERBOUND]], align 464// CHECK-NEXT: [[TMP8:%.*]] = sub i32 [[OMP_FLOOR0_TRIPCOUNT]], 165// CHECK-NEXT: store i32 [[TMP8]], ptr [[P_UPPERBOUND]], align 466// CHECK-NEXT: store i32 1, ptr [[P_STRIDE]], align 467// CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]])68// CHECK-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]], i32 34, ptr [[P_LASTITER]], ptr [[P_LOWERBOUND]], ptr [[P_UPPERBOUND]], ptr [[P_STRIDE]], i32 1, i32 0)69// CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[P_LOWERBOUND]], align 470// CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[P_UPPERBOUND]], align 471// CHECK-NEXT: [[TMP11:%.*]] = sub i32 [[TMP10]], [[TMP9]]72// CHECK-NEXT: [[TMP12:%.*]] = add i32 [[TMP11]], 173// CHECK-NEXT: br label [[OMP_FLOOR0_HEADER:%.*]]74// CHECK: omp_floor0.header:75// CHECK-NEXT: [[OMP_FLOOR0_IV:%.*]] = phi i32 [ 0, [[OMP_FLOOR0_PREHEADER]] ], [ [[OMP_FLOOR0_NEXT:%.*]], [[OMP_FLOOR0_INC:%.*]] ]76// CHECK-NEXT: br label [[OMP_FLOOR0_COND:%.*]]77// CHECK: omp_floor0.cond:78// CHECK-NEXT: [[OMP_FLOOR0_CMP:%.*]] = icmp ult i32 [[OMP_FLOOR0_IV]], [[TMP12]]79// CHECK-NEXT: br i1 [[OMP_FLOOR0_CMP]], label [[OMP_FLOOR0_BODY:%.*]], label [[OMP_FLOOR0_EXIT:%.*]]80// CHECK: omp_floor0.body:81// CHECK-NEXT: [[TMP13:%.*]] = add i32 [[OMP_FLOOR0_IV]], [[TMP9]]82// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[TMP13]], [[TMP4]]83// CHECK-NEXT: [[TMP15:%.*]] = select i1 [[TMP14]], i32 [[TMP5]], i32 1384// CHECK-NEXT: br label [[OMP_TILE0_PREHEADER:%.*]]85// CHECK: omp_tile0.preheader:86// CHECK-NEXT: br label [[OMP_TILE0_HEADER:%.*]]87// CHECK: omp_tile0.header:88// CHECK-NEXT: [[OMP_TILE0_IV:%.*]] = phi i32 [ 0, [[OMP_TILE0_PREHEADER]] ], [ [[OMP_TILE0_NEXT:%.*]], [[OMP_TILE0_INC:%.*]] ]89// CHECK-NEXT: br label [[OMP_TILE0_COND:%.*]]90// CHECK: omp_tile0.cond:91// CHECK-NEXT: [[OMP_TILE0_CMP:%.*]] = icmp ult i32 [[OMP_TILE0_IV]], [[TMP15]]92// CHECK-NEXT: br i1 [[OMP_TILE0_CMP]], label [[OMP_TILE0_BODY:%.*]], label [[OMP_TILE0_EXIT:%.*]]93// CHECK: omp_tile0.body:94// CHECK-NEXT: [[TMP16:%.*]] = mul nuw i32 13, [[TMP13]]95// CHECK-NEXT: [[TMP17:%.*]] = add nuw i32 [[TMP16]], [[OMP_TILE0_IV]]96// CHECK-NEXT: br label [[OMP_LOOP_BODY:%.*]]97// CHECK: omp_loop.body:98// CHECK-NEXT: call void @__captured_stmt.1(ptr [[I]], i32 [[TMP17]], ptr [[AGG_CAPTURED1]])99// CHECK-NEXT: [[TMP18:%.*]] = load ptr, ptr [[B_ADDR]], align 8100// CHECK-NEXT: [[TMP19:%.*]] = load i32, ptr [[I]], align 4101// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP19]] to i64102// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP18]], i64 [[IDXPROM]]103// CHECK-NEXT: [[TMP20:%.*]] = load float, ptr [[ARRAYIDX]], align 4104// CHECK-NEXT: [[TMP21:%.*]] = load ptr, ptr [[C_ADDR]], align 8105// CHECK-NEXT: [[TMP22:%.*]] = load i32, ptr [[I]], align 4106// CHECK-NEXT: [[IDXPROM2:%.*]] = sext i32 [[TMP22]] to i64107// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP21]], i64 [[IDXPROM2]]108// CHECK-NEXT: [[TMP23:%.*]] = load float, ptr [[ARRAYIDX3]], align 4109// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP20]], [[TMP23]]110// CHECK-NEXT: [[TMP24:%.*]] = load ptr, ptr [[D_ADDR]], align 8111// CHECK-NEXT: [[TMP25:%.*]] = load i32, ptr [[I]], align 4112// CHECK-NEXT: [[IDXPROM4:%.*]] = sext i32 [[TMP25]] to i64113// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[TMP24]], i64 [[IDXPROM4]]114// CHECK-NEXT: [[TMP26:%.*]] = load float, ptr [[ARRAYIDX5]], align 4115// CHECK-NEXT: [[MUL6:%.*]] = fmul float [[MUL]], [[TMP26]]116// CHECK-NEXT: [[TMP27:%.*]] = load ptr, ptr [[A_ADDR]], align 8117// CHECK-NEXT: [[TMP28:%.*]] = load i32, ptr [[I]], align 4118// CHECK-NEXT: [[IDXPROM7:%.*]] = sext i32 [[TMP28]] to i64119// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[TMP27]], i64 [[IDXPROM7]]120// CHECK-NEXT: store float [[MUL6]], ptr [[ARRAYIDX8]], align 4121// CHECK-NEXT: br label [[OMP_TILE0_INC]]122// CHECK: omp_tile0.inc:123// CHECK-NEXT: [[OMP_TILE0_NEXT]] = add nuw i32 [[OMP_TILE0_IV]], 1124// CHECK-NEXT: br label [[OMP_TILE0_HEADER]], !llvm.loop [[LOOP3:![0-9]+]]125// CHECK: omp_tile0.exit:126// CHECK-NEXT: br label [[OMP_TILE0_AFTER:%.*]]127// CHECK: omp_tile0.after:128// CHECK-NEXT: br label [[OMP_FLOOR0_INC]]129// CHECK: omp_floor0.inc:130// CHECK-NEXT: [[OMP_FLOOR0_NEXT]] = add nuw i32 [[OMP_FLOOR0_IV]], 1131// CHECK-NEXT: br label [[OMP_FLOOR0_HEADER]]132// CHECK: omp_floor0.exit:133// CHECK-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])134// CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM9:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])135// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM9]])136// CHECK-NEXT: br label [[OMP_FLOOR0_AFTER:%.*]]137// CHECK: omp_floor0.after:138// CHECK-NEXT: br label [[OMP_LOOP_AFTER:%.*]]139// CHECK: omp_loop.after:140// CHECK-NEXT: ret void141//142//143// CHECK-LABEL: define {{[^@]+}}@__captured_stmt144// CHECK-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[DISTANCE:%.*]], ptr noalias noundef [[__CONTEXT:%.*]]) #[[ATTR0]] {145// CHECK-NEXT: entry:146// CHECK-NEXT: [[DISTANCE_ADDR:%.*]] = alloca ptr, align 8147// CHECK-NEXT: [[__CONTEXT_ADDR:%.*]] = alloca ptr, align 8148// CHECK-NEXT: [[DOTSTART:%.*]] = alloca i32, align 4149// CHECK-NEXT: [[DOTSTOP:%.*]] = alloca i32, align 4150// CHECK-NEXT: [[DOTSTEP:%.*]] = alloca i32, align 4151// CHECK-NEXT: store ptr [[DISTANCE]], ptr [[DISTANCE_ADDR]], align 8152// CHECK-NEXT: store ptr [[__CONTEXT]], ptr [[__CONTEXT_ADDR]], align 8153// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__CONTEXT_ADDR]], align 8154// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP0]], i32 0, i32 0155// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8156// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4157// CHECK-NEXT: store i32 [[TMP3]], ptr [[DOTSTART]], align 4158// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP0]], i32 0, i32 1159// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8160// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4161// CHECK-NEXT: store i32 [[TMP6]], ptr [[DOTSTOP]], align 4162// CHECK-NEXT: store i32 1, ptr [[DOTSTEP]], align 4163// CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTSTART]], align 4164// CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTSTOP]], align 4165// CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP7]], [[TMP8]]166// CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]167// CHECK: cond.true:168// CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTSTOP]], align 4169// CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTSTART]], align 4170// CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP9]], [[TMP10]]171// CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTSTEP]], align 4172// CHECK-NEXT: [[SUB1:%.*]] = sub i32 [[TMP11]], 1173// CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]]174// CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTSTEP]], align 4175// CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP12]]176// CHECK-NEXT: br label [[COND_END:%.*]]177// CHECK: cond.false:178// CHECK-NEXT: br label [[COND_END]]179// CHECK: cond.end:180// CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[DIV]], [[COND_TRUE]] ], [ 0, [[COND_FALSE]] ]181// CHECK-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DISTANCE_ADDR]], align 8182// CHECK-NEXT: store i32 [[COND]], ptr [[TMP13]], align 4183// CHECK-NEXT: ret void184//185//186// CHECK-LABEL: define {{[^@]+}}@__captured_stmt.1187// CHECK-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[LOOPVAR:%.*]], i32 noundef [[LOGICAL:%.*]], ptr noalias noundef [[__CONTEXT:%.*]]) #[[ATTR0]] {188// CHECK-NEXT: entry:189// CHECK-NEXT: [[LOOPVAR_ADDR:%.*]] = alloca ptr, align 8190// CHECK-NEXT: [[LOGICAL_ADDR:%.*]] = alloca i32, align 4191// CHECK-NEXT: [[__CONTEXT_ADDR:%.*]] = alloca ptr, align 8192// CHECK-NEXT: store ptr [[LOOPVAR]], ptr [[LOOPVAR_ADDR]], align 8193// CHECK-NEXT: store i32 [[LOGICAL]], ptr [[LOGICAL_ADDR]], align 4194// CHECK-NEXT: store ptr [[__CONTEXT]], ptr [[__CONTEXT_ADDR]], align 8195// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__CONTEXT_ADDR]], align 8196// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP0]], i32 0, i32 0197// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4198// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[LOGICAL_ADDR]], align 4199// CHECK-NEXT: [[MUL:%.*]] = mul i32 1, [[TMP3]]200// CHECK-NEXT: [[ADD:%.*]] = add i32 [[TMP2]], [[MUL]]201// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[LOOPVAR_ADDR]], align 8202// CHECK-NEXT: store i32 [[ADD]], ptr [[TMP4]], align 4203// CHECK-NEXT: ret void204//205