69 lines · c
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-globals --global-value-regex "[A-Za-z].*"2// RUN: %clang_cc1 -triple=x86_64-unknown-linux %s -emit-llvm -o - | FileCheck %s3 4// This tests all kinds of hard cases with initializers and5// array subscripts. This corresponds to PR487.6 7struct X { int a[2]; };8extern int bar();9 10//.11// CHECK: @test.i23 = internal global i32 4, align 412// CHECK: @i = global i32 4, align 413// CHECK: @Arr = global [100 x i32] zeroinitializer, align 1614// CHECK: @foo2.X = internal global ptr getelementptr (i8, ptr @Arr, i64 196), align 815// CHECK: @foo2.i23 = internal global i32 0, align 416//.17// CHECK-LABEL: define {{[^@]+}}@test18// CHECK-SAME: () #[[ATTR0:[0-9]+]] {19// CHECK-NEXT: entry:20// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @test.i23, align 421// CHECK-NEXT: ret i32 [[TMP0]]22//23int test(void) {24 static int i23 = (int) &(((struct X *)0)->a[1]);25 return i23;26}27 28int i = (int) &( ((struct X *)0) -> a[1]);29 30int Arr[100];31 32// CHECK-LABEL: define {{[^@]+}}@foo33// CHECK-SAME: (i32 noundef [[I:%.*]]) #[[ATTR0]] {34// CHECK-NEXT: entry:35// CHECK-NEXT: [[I_ADDR:%.*]] = alloca i32, align 436// CHECK-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 437// CHECK-NEXT: [[CALL:%.*]] = call i32 (ptr, ...) @bar(ptr noundef getelementptr inbounds ([100 x i32], ptr @Arr, i64 0, i64 49))38// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 439// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i6440// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i32], ptr @Arr, i64 0, i64 [[IDXPROM]]41// CHECK-NEXT: [[CALL1:%.*]] = call i32 (ptr, ...) @bar(ptr noundef [[ARRAYIDX]])42// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]]43// CHECK-NEXT: ret i32 [[ADD]]44//45int foo(int i) { return bar(&Arr[49])+bar(&Arr[i]); }46// CHECK-LABEL: define {{[^@]+}}@foo247// CHECK-SAME: (i32 noundef [[I:%.*]]) #[[ATTR0]] {48// CHECK-NEXT: entry:49// CHECK-NEXT: [[I_ADDR:%.*]] = alloca i32, align 450// CHECK-NEXT: [[P:%.*]] = alloca ptr, align 851// CHECK-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 452// CHECK-NEXT: store ptr @Arr, ptr [[P]], align 853// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 854// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i32 155// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[P]], align 856// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 457// CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[TMP1]] to i6458// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr @Arr, i64 [[IDX_EXT]]59// CHECK-NEXT: [[CALL:%.*]] = call i32 (ptr, ...) @bar(ptr noundef [[ADD_PTR]])60// CHECK-NEXT: ret i32 [[CALL]]61//62int foo2(int i) {63 static const int *X = &Arr[49];64 static int i23 = (int) &( ((struct X *)0) -> a[0]);65 int *P = Arr;66 ++P;67 return bar(Arr+i);68}69