blob: 7bcaf56adf65239ebf4871970efb55f8db873cba [file] [edit]
// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
void h(int, int);
void break_continue() {
template for (auto x : {1, 2}) {
break;
h(1, x);
}
template for (auto x : {3, 4}) {
continue;
h(2, x);
}
template for (auto x : {5, 6}) {
if (x == 2) break;
h(3, x);
}
template for (auto x : {7, 8}) {
if (x == 2) continue;
h(4, x);
}
}
int break_continue_nested() {
int sum = 0;
template for (auto x : {1, 2}) {
template for (auto y : {3, 4}) {
if (x == 2) break;
sum += y;
}
sum += x;
}
template for (auto x : {5, 6}) {
template for (auto y : {7, 8}) {
if (x == 6) continue;
sum += y;
}
sum += x;
}
return sum;
}
void label() {
// Only local labels are allowed in expansion statements.
template for (auto x : {1, 2, 3}) {
__label__ a;
if (x == 1) goto a;
h(1, x);
a:;
}
}
void nested_label() {
template for (auto x : {1, 2}) {
__label__ a;
template for (auto y : {3, 4}) {
if (y == 3) goto a;
if (y == 4) goto end;
h(x, y);
}
a:;
}
end:
}
// CHECK-LABEL: define {{.*}} void @_Z14break_continuev()
// CHECK: entry:
// CHECK-NEXT: %x = alloca i32, align 4
// CHECK-NEXT: %x1 = alloca i32, align 4
// CHECK-NEXT: %x2 = alloca i32, align 4
// CHECK-NEXT: %x3 = alloca i32, align 4
// CHECK-NEXT: %x5 = alloca i32, align 4
// CHECK-NEXT: %x7 = alloca i32, align 4
// CHECK-NEXT: %x12 = alloca i32, align 4
// CHECK-NEXT: %x17 = alloca i32, align 4
// CHECK-NEXT: store i32 1, ptr %x, align 4
// CHECK-NEXT: br label %expand.end
// CHECK: expand.end:
// CHECK-NEXT: store i32 3, ptr %x2, align 4
// CHECK-NEXT: br label %expand.next
// CHECK: expand.next:
// CHECK-NEXT: store i32 4, ptr %x3, align 4
// CHECK-NEXT: br label %expand.end4
// CHECK: expand.end4:
// CHECK-NEXT: store i32 5, ptr %x5, align 4
// CHECK-NEXT: %0 = load i32, ptr %x5, align 4
// CHECK-NEXT: %cmp = icmp eq i32 %0, 2
// CHECK-NEXT: br i1 %cmp, label %if.then, label %if.end
// CHECK: if.then:
// CHECK-NEXT: br label %expand.end11
// CHECK: if.end:
// CHECK-NEXT: %1 = load i32, ptr %x5, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} 3, i32 {{.*}} %1)
// CHECK-NEXT: br label %expand.next6
// CHECK: expand.next6:
// CHECK-NEXT: store i32 6, ptr %x7, align 4
// CHECK-NEXT: %2 = load i32, ptr %x7, align 4
// CHECK-NEXT: %cmp8 = icmp eq i32 %2, 2
// CHECK-NEXT: br i1 %cmp8, label %if.then9, label %if.end10
// CHECK: if.then9:
// CHECK-NEXT: br label %expand.end11
// CHECK: if.end10:
// CHECK-NEXT: %3 = load i32, ptr %x7, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} 3, i32 {{.*}} %3)
// CHECK-NEXT: br label %expand.end11
// CHECK: expand.end11:
// CHECK-NEXT: store i32 7, ptr %x12, align 4
// CHECK-NEXT: %4 = load i32, ptr %x12, align 4
// CHECK-NEXT: %cmp13 = icmp eq i32 %4, 2
// CHECK-NEXT: br i1 %cmp13, label %if.then14, label %if.end15
// CHECK: if.then14:
// CHECK-NEXT: br label %expand.next16
// CHECK: if.end15:
// CHECK-NEXT: %5 = load i32, ptr %x12, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} 4, i32 {{.*}} %5)
// CHECK-NEXT: br label %expand.next16
// CHECK: expand.next16:
// CHECK-NEXT: store i32 8, ptr %x17, align 4
// CHECK-NEXT: %6 = load i32, ptr %x17, align 4
// CHECK-NEXT: %cmp18 = icmp eq i32 %6, 2
// CHECK-NEXT: br i1 %cmp18, label %if.then19, label %if.end20
// CHECK: if.then19:
// CHECK-NEXT: br label %expand.end21
// CHECK: if.end20:
// CHECK-NEXT: %7 = load i32, ptr %x17, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} 4, i32 {{.*}} %7)
// CHECK-NEXT: br label %expand.end21
// CHECK: expand.end21:
// CHECK-NEXT: ret void
// CHECK-LABEL: define {{.*}} i32 @_Z21break_continue_nestedv()
// CHECK: entry:
// CHECK-NEXT: %sum = alloca i32, align 4
// CHECK-NEXT: %x = alloca i32, align 4
// CHECK-NEXT: %y = alloca i32, align 4
// CHECK-NEXT: %y1 = alloca i32, align 4
// CHECK-NEXT: %x8 = alloca i32, align 4
// CHECK-NEXT: %y9 = alloca i32, align 4
// CHECK-NEXT: %y15 = alloca i32, align 4
// CHECK-NEXT: %x23 = alloca i32, align 4
// CHECK-NEXT: %y24 = alloca i32, align 4
// CHECK-NEXT: %y30 = alloca i32, align 4
// CHECK-NEXT: %x38 = alloca i32, align 4
// CHECK-NEXT: %y39 = alloca i32, align 4
// CHECK-NEXT: %y45 = alloca i32, align 4
// CHECK-NEXT: store i32 0, ptr %sum, align 4
// CHECK-NEXT: store i32 1, ptr %x, align 4
// CHECK-NEXT: store i32 3, ptr %y, align 4
// CHECK-NEXT: %0 = load i32, ptr %x, align 4
// CHECK-NEXT: %cmp = icmp eq i32 %0, 2
// CHECK-NEXT: br i1 %cmp, label %if.then, label %if.end
// CHECK: if.then:
// CHECK-NEXT: br label %expand.end
// CHECK: if.end:
// CHECK-NEXT: %1 = load i32, ptr %y, align 4
// CHECK-NEXT: %2 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add = add nsw i32 %2, %1
// CHECK-NEXT: store i32 %add, ptr %sum, align 4
// CHECK-NEXT: br label %expand.next
// CHECK: expand.next:
// CHECK-NEXT: store i32 4, ptr %y1, align 4
// CHECK-NEXT: %3 = load i32, ptr %x, align 4
// CHECK-NEXT: %cmp2 = icmp eq i32 %3, 2
// CHECK-NEXT: br i1 %cmp2, label %if.then3, label %if.end4
// CHECK: if.then3:
// CHECK-NEXT: br label %expand.end
// CHECK: if.end4:
// CHECK-NEXT: %4 = load i32, ptr %y1, align 4
// CHECK-NEXT: %5 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add5 = add nsw i32 %5, %4
// CHECK-NEXT: store i32 %add5, ptr %sum, align 4
// CHECK-NEXT: br label %expand.end
// CHECK: expand.end:
// CHECK-NEXT: %6 = load i32, ptr %x, align 4
// CHECK-NEXT: %7 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add6 = add nsw i32 %7, %6
// CHECK-NEXT: store i32 %add6, ptr %sum, align 4
// CHECK-NEXT: br label %expand.next7
// CHECK: expand.next7:
// CHECK-NEXT: store i32 2, ptr %x8, align 4
// CHECK-NEXT: store i32 3, ptr %y9, align 4
// CHECK-NEXT: %8 = load i32, ptr %x8, align 4
// CHECK-NEXT: %cmp10 = icmp eq i32 %8, 2
// CHECK-NEXT: br i1 %cmp10, label %if.then11, label %if.end12
// CHECK: if.then11:
// CHECK-NEXT: br label %expand.end20
// CHECK: if.end12:
// CHECK-NEXT: %9 = load i32, ptr %y9, align 4
// CHECK-NEXT: %10 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add13 = add nsw i32 %10, %9
// CHECK-NEXT: store i32 %add13, ptr %sum, align 4
// CHECK-NEXT: br label %expand.next14
// CHECK: expand.next14:
// CHECK-NEXT: store i32 4, ptr %y15, align 4
// CHECK-NEXT: %11 = load i32, ptr %x8, align 4
// CHECK-NEXT: %cmp16 = icmp eq i32 %11, 2
// CHECK-NEXT: br i1 %cmp16, label %if.then17, label %if.end18
// CHECK: if.then17:
// CHECK-NEXT: br label %expand.end20
// CHECK: if.end18:
// CHECK-NEXT: %12 = load i32, ptr %y15, align 4
// CHECK-NEXT: %13 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add19 = add nsw i32 %13, %12
// CHECK-NEXT: store i32 %add19, ptr %sum, align 4
// CHECK-NEXT: br label %expand.end20
// CHECK: expand.end20:
// CHECK-NEXT: %14 = load i32, ptr %x8, align 4
// CHECK-NEXT: %15 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add21 = add nsw i32 %15, %14
// CHECK-NEXT: store i32 %add21, ptr %sum, align 4
// CHECK-NEXT: br label %expand.end22
// CHECK: expand.end22:
// CHECK-NEXT: store i32 5, ptr %x23, align 4
// CHECK-NEXT: store i32 7, ptr %y24, align 4
// CHECK-NEXT: %16 = load i32, ptr %x23, align 4
// CHECK-NEXT: %cmp25 = icmp eq i32 %16, 6
// CHECK-NEXT: br i1 %cmp25, label %if.then26, label %if.end27
// CHECK: if.then26:
// CHECK-NEXT: br label %expand.next29
// CHECK: if.end27:
// CHECK-NEXT: %17 = load i32, ptr %y24, align 4
// CHECK-NEXT: %18 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add28 = add nsw i32 %18, %17
// CHECK-NEXT: store i32 %add28, ptr %sum, align 4
// CHECK-NEXT: br label %expand.next29
// CHECK: expand.next29:
// CHECK-NEXT: store i32 8, ptr %y30, align 4
// CHECK-NEXT: %19 = load i32, ptr %x23, align 4
// CHECK-NEXT: %cmp31 = icmp eq i32 %19, 6
// CHECK-NEXT: br i1 %cmp31, label %if.then32, label %if.end33
// CHECK: if.then32:
// CHECK-NEXT: br label %expand.end35
// CHECK: if.end33:
// CHECK-NEXT: %20 = load i32, ptr %y30, align 4
// CHECK-NEXT: %21 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add34 = add nsw i32 %21, %20
// CHECK-NEXT: store i32 %add34, ptr %sum, align 4
// CHECK-NEXT: br label %expand.end35
// CHECK: expand.end35:
// CHECK-NEXT: %22 = load i32, ptr %x23, align 4
// CHECK-NEXT: %23 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add36 = add nsw i32 %23, %22
// CHECK-NEXT: store i32 %add36, ptr %sum, align 4
// CHECK-NEXT: br label %expand.next37
// CHECK: expand.next37:
// CHECK-NEXT: store i32 6, ptr %x38, align 4
// CHECK-NEXT: store i32 7, ptr %y39, align 4
// CHECK-NEXT: %24 = load i32, ptr %x38, align 4
// CHECK-NEXT: %cmp40 = icmp eq i32 %24, 6
// CHECK-NEXT: br i1 %cmp40, label %if.then41, label %if.end42
// CHECK: if.then41:
// CHECK-NEXT: br label %expand.next44
// CHECK: if.end42:
// CHECK-NEXT: %25 = load i32, ptr %y39, align 4
// CHECK-NEXT: %26 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add43 = add nsw i32 %26, %25
// CHECK-NEXT: store i32 %add43, ptr %sum, align 4
// CHECK-NEXT: br label %expand.next44
// CHECK: expand.next44:
// CHECK-NEXT: store i32 8, ptr %y45, align 4
// CHECK-NEXT: %27 = load i32, ptr %x38, align 4
// CHECK-NEXT: %cmp46 = icmp eq i32 %27, 6
// CHECK-NEXT: br i1 %cmp46, label %if.then47, label %if.end48
// CHECK: if.then47:
// CHECK-NEXT: br label %expand.end50
// CHECK: if.end48:
// CHECK-NEXT: %28 = load i32, ptr %y45, align 4
// CHECK-NEXT: %29 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add49 = add nsw i32 %29, %28
// CHECK-NEXT: store i32 %add49, ptr %sum, align 4
// CHECK-NEXT: br label %expand.end50
// CHECK: expand.end50:
// CHECK-NEXT: %30 = load i32, ptr %x38, align 4
// CHECK-NEXT: %31 = load i32, ptr %sum, align 4
// CHECK-NEXT: %add51 = add nsw i32 %31, %30
// CHECK-NEXT: store i32 %add51, ptr %sum, align 4
// CHECK-NEXT: br label %expand.end52
// CHECK: expand.end52:
// CHECK-NEXT: %32 = load i32, ptr %sum, align 4
// CHECK-NEXT: ret i32 %32
// CHECK-LABEL: define {{.*}} void @_Z5labelv()
// CHECK: entry:
// CHECK-NEXT: %x = alloca i32, align 4
// CHECK-NEXT: %x1 = alloca i32, align 4
// CHECK-NEXT: %x7 = alloca i32, align 4
// CHECK-NEXT: store i32 1, ptr %x, align 4
// CHECK-NEXT: %0 = load i32, ptr %x, align 4
// CHECK-NEXT: %cmp = icmp eq i32 %0, 1
// CHECK-NEXT: br i1 %cmp, label %if.then, label %if.end
// CHECK: if.then:
// CHECK-NEXT: br label %a
// CHECK: if.end:
// CHECK-NEXT: %1 = load i32, ptr %x, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} 1, i32 {{.*}} %1)
// CHECK-NEXT: br label %a
// CHECK: a:
// CHECK-NEXT: br label %expand.next
// CHECK: expand.next:
// CHECK-NEXT: store i32 2, ptr %x1, align 4
// CHECK-NEXT: %2 = load i32, ptr %x1, align 4
// CHECK-NEXT: %cmp2 = icmp eq i32 %2, 1
// CHECK-NEXT: br i1 %cmp2, label %if.then3, label %if.end4
// CHECK: if.then3:
// CHECK-NEXT: br label %a5
// CHECK: if.end4:
// CHECK-NEXT: %3 = load i32, ptr %x1, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} 1, i32 {{.*}} %3)
// CHECK-NEXT: br label %a5
// CHECK: a5:
// CHECK-NEXT: br label %expand.next6
// CHECK: expand.next6:
// CHECK-NEXT: store i32 3, ptr %x7, align 4
// CHECK-NEXT: %4 = load i32, ptr %x7, align 4
// CHECK-NEXT: %cmp8 = icmp eq i32 %4, 1
// CHECK-NEXT: br i1 %cmp8, label %if.then9, label %if.end10
// CHECK: if.then9:
// CHECK-NEXT: br label %a11
// CHECK: if.end10:
// CHECK-NEXT: %5 = load i32, ptr %x7, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} 1, i32 {{.*}} %5)
// CHECK-NEXT: br label %a11
// CHECK: a11:
// CHECK-NEXT: br label %expand.end
// CHECK: expand.end:
// CHECK-NEXT: ret void
// CHECK-LABEL: define {{.*}} void @_Z12nested_labelv()
// CHECK: entry:
// CHECK-NEXT: %x = alloca i32, align 4
// CHECK-NEXT: %y = alloca i32, align 4
// CHECK-NEXT: %y4 = alloca i32, align 4
// CHECK-NEXT: %x12 = alloca i32, align 4
// CHECK-NEXT: %y13 = alloca i32, align 4
// CHECK-NEXT: %y21 = alloca i32, align 4
// CHECK-NEXT: store i32 1, ptr %x, align 4
// CHECK-NEXT: store i32 3, ptr %y, align 4
// CHECK-NEXT: %0 = load i32, ptr %y, align 4
// CHECK-NEXT: %cmp = icmp eq i32 %0, 3
// CHECK-NEXT: br i1 %cmp, label %if.then, label %if.end
// CHECK: if.then:
// CHECK-NEXT: br label %a
// CHECK: if.end:
// CHECK-NEXT: %1 = load i32, ptr %y, align 4
// CHECK-NEXT: %cmp1 = icmp eq i32 %1, 4
// CHECK-NEXT: br i1 %cmp1, label %if.then2, label %if.end3
// CHECK: if.then2:
// CHECK-NEXT: br label %end
// CHECK: if.end3:
// CHECK-NEXT: %2 = load i32, ptr %x, align 4
// CHECK-NEXT: %3 = load i32, ptr %y, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} %2, i32 {{.*}} %3)
// CHECK-NEXT: br label %expand.next
// CHECK: expand.next:
// CHECK-NEXT: store i32 4, ptr %y4, align 4
// CHECK-NEXT: %4 = load i32, ptr %y4, align 4
// CHECK-NEXT: %cmp5 = icmp eq i32 %4, 3
// CHECK-NEXT: br i1 %cmp5, label %if.then6, label %if.end7
// CHECK: if.then6:
// CHECK-NEXT: br label %a
// CHECK: if.end7:
// CHECK-NEXT: %5 = load i32, ptr %y4, align 4
// CHECK-NEXT: %cmp8 = icmp eq i32 %5, 4
// CHECK-NEXT: br i1 %cmp8, label %if.then9, label %if.end10
// CHECK: if.then9:
// CHECK-NEXT: br label %end
// CHECK: if.end10:
// CHECK-NEXT: %6 = load i32, ptr %x, align 4
// CHECK-NEXT: %7 = load i32, ptr %y4, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} %6, i32 {{.*}} %7)
// CHECK-NEXT: br label %expand.end
// CHECK: expand.end:
// CHECK-NEXT: br label %a
// CHECK: a:
// CHECK-NEXT: br label %expand.next11
// CHECK: expand.next11:
// CHECK-NEXT: store i32 2, ptr %x12, align 4
// CHECK-NEXT: store i32 3, ptr %y13, align 4
// CHECK-NEXT: %8 = load i32, ptr %y13, align 4
// CHECK-NEXT: %cmp14 = icmp eq i32 %8, 3
// CHECK-NEXT: br i1 %cmp14, label %if.then15, label %if.end16
// CHECK: if.then15:
// CHECK-NEXT: br label %a29
// CHECK: if.end16:
// CHECK-NEXT: %9 = load i32, ptr %y13, align 4
// CHECK-NEXT: %cmp17 = icmp eq i32 %9, 4
// CHECK-NEXT: br i1 %cmp17, label %if.then18, label %if.end19
// CHECK: if.then18:
// CHECK-NEXT: br label %end
// CHECK: if.end19:
// CHECK-NEXT: %10 = load i32, ptr %x12, align 4
// CHECK-NEXT: %11 = load i32, ptr %y13, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} %10, i32 {{.*}} %11)
// CHECK-NEXT: br label %expand.next20
// CHECK: expand.next20:
// CHECK-NEXT: store i32 4, ptr %y21, align 4
// CHECK-NEXT: %12 = load i32, ptr %y21, align 4
// CHECK-NEXT: %cmp22 = icmp eq i32 %12, 3
// CHECK-NEXT: br i1 %cmp22, label %if.then23, label %if.end24
// CHECK: if.then23:
// CHECK-NEXT: br label %a29
// CHECK: if.end24:
// CHECK-NEXT: %13 = load i32, ptr %y21, align 4
// CHECK-NEXT: %cmp25 = icmp eq i32 %13, 4
// CHECK-NEXT: br i1 %cmp25, label %if.then26, label %if.end27
// CHECK: if.then26:
// CHECK-NEXT: br label %end
// CHECK: if.end27:
// CHECK-NEXT: %14 = load i32, ptr %x12, align 4
// CHECK-NEXT: %15 = load i32, ptr %y21, align 4
// CHECK-NEXT: call void @_Z1hii(i32 {{.*}} %14, i32 {{.*}} %15)
// CHECK-NEXT: br label %expand.end28
// CHECK: expand.end28:
// CHECK-NEXT: br label %a29
// CHECK: a29:
// CHECK-NEXT: br label %expand.end30
// CHECK: expand.end30:
// CHECK-NEXT: br label %end
// CHECK: end:
// CHECK-NEXT: ret void