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[.].+[.|,]" 2 // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp %s 3 // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefix=IR 4 5 // Check same results after serialization round-trip 6 // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -emit-pch -o %t %s 7 // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=IR-PCH 8 9 // expected-no-diagnostics 10 11 #ifndef HEADER 12 #define HEADER 13 14 void foo(int t) { 15 16 int i, j, z; 17 #pragma omp loop collapse(2) reduction(+:z) lastprivate(j) bind(thread) 18 for (int i = 0; i<t; ++i) 19 for (j = 0; j<t; ++j) 20 z += i+j; 21 } 22 #endif 23 // IR-LABEL: define {{[^@]+}}@_Z3fooi 24 // IR-SAME: (i32 noundef [[T:%.*]]) #[[ATTR0:[0-9]+]] { 25 // IR-NEXT: entry: 26 // IR-NEXT: [[T_ADDR:%.*]] = alloca i32, align 4 27 // IR-NEXT: [[I:%.*]] = alloca i32, align 4 28 // IR-NEXT: [[J:%.*]] = alloca i32, align 4 29 // IR-NEXT: [[Z:%.*]] = alloca i32, align 4 30 // IR-NEXT: [[I1:%.*]] = alloca i32, align 4 31 // IR-NEXT: store i32 [[T]], ptr [[T_ADDR]], align 4 32 // IR-NEXT: store i32 0, ptr [[I1]], align 4 33 // IR-NEXT: br label [[FOR_COND:%.*]] 34 // IR: for.cond: 35 // IR-NEXT: [[TMP0:%.*]] = load i32, ptr [[I1]], align 4 36 // IR-NEXT: [[TMP1:%.*]] = load i32, ptr [[T_ADDR]], align 4 37 // IR-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]] 38 // IR-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END8:%.*]] 39 // IR: for.body: 40 // IR-NEXT: store i32 0, ptr [[J]], align 4 41 // IR-NEXT: br label [[FOR_COND2:%.*]] 42 // IR: for.cond2: 43 // IR-NEXT: [[TMP2:%.*]] = load i32, ptr [[J]], align 4 44 // IR-NEXT: [[TMP3:%.*]] = load i32, ptr [[T_ADDR]], align 4 45 // IR-NEXT: [[CMP3:%.*]] = icmp slt i32 [[TMP2]], [[TMP3]] 46 // IR-NEXT: br i1 [[CMP3]], label [[FOR_BODY4:%.*]], label [[FOR_END:%.*]] 47 // IR: for.body4: 48 // IR-NEXT: [[TMP4:%.*]] = load i32, ptr [[I1]], align 4 49 // IR-NEXT: [[TMP5:%.*]] = load i32, ptr [[J]], align 4 50 // IR-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], [[TMP5]] 51 // IR-NEXT: [[TMP6:%.*]] = load i32, ptr [[Z]], align 4 52 // IR-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP6]], [[ADD]] 53 // IR-NEXT: store i32 [[ADD5]], ptr [[Z]], align 4 54 // IR-NEXT: br label [[FOR_INC:%.*]] 55 // IR: for.inc: 56 // IR-NEXT: [[TMP7:%.*]] = load i32, ptr [[J]], align 4 57 // IR-NEXT: [[INC:%.*]] = add nsw i32 [[TMP7]], 1 58 // IR-NEXT: store i32 [[INC]], ptr [[J]], align 4 59 // IR-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP3:![0-9]+]] 60 // IR: for.end: 61 // IR-NEXT: br label [[FOR_INC6:%.*]] 62 // IR: for.inc6: 63 // IR-NEXT: [[TMP8:%.*]] = load i32, ptr [[I1]], align 4 64 // IR-NEXT: [[INC7:%.*]] = add nsw i32 [[TMP8]], 1 65 // IR-NEXT: store i32 [[INC7]], ptr [[I1]], align 4 66 // IR-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]] 67 // IR: for.end8: 68 // IR-NEXT: ret void 69 // 70 // 71 // IR-PCH-LABEL: define {{[^@]+}}@_Z3fooi 72 // IR-PCH-SAME: (i32 noundef [[T:%.*]]) #[[ATTR0:[0-9]+]] { 73 // IR-PCH-NEXT: entry: 74 // IR-PCH-NEXT: [[T_ADDR:%.*]] = alloca i32, align 4 75 // IR-PCH-NEXT: [[I:%.*]] = alloca i32, align 4 76 // IR-PCH-NEXT: [[J:%.*]] = alloca i32, align 4 77 // IR-PCH-NEXT: [[Z:%.*]] = alloca i32, align 4 78 // IR-PCH-NEXT: [[I1:%.*]] = alloca i32, align 4 79 // IR-PCH-NEXT: store i32 [[T]], ptr [[T_ADDR]], align 4 80 // IR-PCH-NEXT: store i32 0, ptr [[I1]], align 4 81 // IR-PCH-NEXT: br label [[FOR_COND:%.*]] 82 // IR-PCH: for.cond: 83 // IR-PCH-NEXT: [[TMP0:%.*]] = load i32, ptr [[I1]], align 4 84 // IR-PCH-NEXT: [[TMP1:%.*]] = load i32, ptr [[T_ADDR]], align 4 85 // IR-PCH-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]] 86 // IR-PCH-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END8:%.*]] 87 // IR-PCH: for.body: 88 // IR-PCH-NEXT: store i32 0, ptr [[J]], align 4 89 // IR-PCH-NEXT: br label [[FOR_COND2:%.*]] 90 // IR-PCH: for.cond2: 91 // IR-PCH-NEXT: [[TMP2:%.*]] = load i32, ptr [[J]], align 4 92 // IR-PCH-NEXT: [[TMP3:%.*]] = load i32, ptr [[T_ADDR]], align 4 93 // IR-PCH-NEXT: [[CMP3:%.*]] = icmp slt i32 [[TMP2]], [[TMP3]] 94 // IR-PCH-NEXT: br i1 [[CMP3]], label [[FOR_BODY4:%.*]], label [[FOR_END:%.*]] 95 // IR-PCH: for.body4: 96 // IR-PCH-NEXT: [[TMP4:%.*]] = load i32, ptr [[I1]], align 4 97 // IR-PCH-NEXT: [[TMP5:%.*]] = load i32, ptr [[J]], align 4 98 // IR-PCH-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], [[TMP5]] 99 // IR-PCH-NEXT: [[TMP6:%.*]] = load i32, ptr [[Z]], align 4 100 // IR-PCH-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP6]], [[ADD]] 101 // IR-PCH-NEXT: store i32 [[ADD5]], ptr [[Z]], align 4 102 // IR-PCH-NEXT: br label [[FOR_INC:%.*]] 103 // IR-PCH: for.inc: 104 // IR-PCH-NEXT: [[TMP7:%.*]] = load i32, ptr [[J]], align 4 105 // IR-PCH-NEXT: [[INC:%.*]] = add nsw i32 [[TMP7]], 1 106 // IR-PCH-NEXT: store i32 [[INC]], ptr [[J]], align 4 107 // IR-PCH-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP3:![0-9]+]] 108 // IR-PCH: for.end: 109 // IR-PCH-NEXT: br label [[FOR_INC6:%.*]] 110 // IR-PCH: for.inc6: 111 // IR-PCH-NEXT: [[TMP8:%.*]] = load i32, ptr [[I1]], align 4 112 // IR-PCH-NEXT: [[INC7:%.*]] = add nsw i32 [[TMP8]], 1 113 // IR-PCH-NEXT: store i32 [[INC7]], ptr [[I1]], align 4 114 // IR-PCH-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]] 115 // IR-PCH: for.end8: 116 // IR-PCH-NEXT: ret void 117 // 118