// RUN: %clang_cc1 -fms-extensions -emit-llvm -o - %s | FileCheck %s // CHECK: %struct.test = type { i32, %struct.nested2, i32 } // CHECK: %struct.nested2 = type { i32, %struct.nested1, i32 } // CHECK: %struct.nested1 = type { i32, i32 } typedef struct nested1 { int a1; int b1; } NESTED1; struct nested2 { int a; NESTED1; int b; }; struct test { int x; struct nested2; int y; }; void foo(void) { // CHECK: %var = alloca %struct.test, align 4 struct test var; // CHECK: getelementptr inbounds nuw %struct.test, ptr %var, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested2, ptr %{{.*}}, i32 0, i32 0 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var.a; // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %var, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested2, ptr %{{.*}}, i32 0, i32 2 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var.b; // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %var, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested2, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested1, ptr %{{.*}}, i32 0, i32 0 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var.a1; // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %{{.*}}var, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested2, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested1, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var.b1; // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %var, i32 0, i32 0 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var.x; // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %var, i32 0, i32 2 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var.y; } void foo2(struct test* var) { // CHECK: alloca ptr, align // CHECK-NEXT: store ptr %var, ptr %{{.*}}, align // CHECK-NEXT: load ptr, ptr %{{.*}}, align // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested2, ptr %{{.*}}, i32 0, i32 0 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var->a; // CHECK-NEXT: load ptr, ptr %{{.*}}, align // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested2, ptr %{{.*}}, i32 0, i32 2 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var->b; // CHECK-NEXT: load ptr, ptr %{{.*}}, align // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested2, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested1, ptr %{{.*}}, i32 0, i32 0 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var->a1; // CHECK-NEXT: load ptr, ptr %{{.*}}, align // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested2, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: getelementptr inbounds nuw %struct.nested1, ptr %{{.*}}, i32 0, i32 1 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var->b1; // CHECK-NEXT: load ptr, ptr %{{.*}}, align // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %{{.*}}, i32 0, i32 0 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var->x; // CHECK-NEXT: load ptr, ptr %{{.*}}, align // CHECK-NEXT: getelementptr inbounds nuw %struct.test, ptr %{{.*}}, i32 0, i32 2 // CHECK-NEXT: load i32, ptr %{{.*}}, align 4 var->y; }