// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fenable-matrix -emit-llvm -disable-llvm-optzns -o - %s | FileCheck %s

// Check that we correctly deal with placeholder expressions.

typedef double double4x2 __attribute__((matrix_type(4, 2)));
typedef double double2x4 __attribute__((matrix_type(2, 4)));

__attribute__((objc_root_class))
@interface DoubleMatrixValue
@property double4x2 value;
@end

void test_transpose_placeholder_get(DoubleMatrixValue *m, double2x4 *r) {
  // CHECK-LABEL: define{{.*}} void @test_transpose_placeholder_get(
  // CHECK:         [[MATRIX:%.*]] = call <8 x double> bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to <8 x double> (i8*, i8*)*)(
  // CHECK-NEXT:   [[MT:%.*]] = call <8 x double> @llvm.matrix.transpose.v8f64(<8 x double> %call, i32 4, i32 2)
  // CHECK-NEXT:   [[R_ADDR:%.*]] = load [8 x double]*, [8 x double]** %r.addr, align 8
  // CHECK-NEXT:   [[R_ADDR_C:%.*]] = bitcast [8 x double]* [[R_ADDR]] to <8 x double>*
  // CHECK-NEXT:    store <8 x double> [[MT]], <8 x double>* [[R_ADDR_C]], align 8
  // CHECK-NEXT:    ret void

  *r = __builtin_matrix_transpose(m.value);
}

typedef unsigned u3x4 __attribute__((matrix_type(3, 4)));
typedef unsigned u4x3 __attribute__((matrix_type(4, 3)));

__attribute__((objc_root_class))
@interface UnsignedMatrixValue
@property u3x4 value;
@end

void test_transpose_placeholder_set(UnsignedMatrixValue *m, u4x3 *r) {
  // CHECK-LABEL: define{{.*}} void @test_transpose_placeholder_set(
  // CHECK:         [[MATRIX:%.*]] = load <12 x i32>, <12 x i32>* {{.*}}, align 4
  // CHECK-NEXT:    [[MT:%.*]] = call <12 x i32> @llvm.matrix.transpose.v12i32(<12 x i32> [[MATRIX]], i32 4, i32 3)
  // CHECK:         call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, <12 x i32>)*)(i8* {{.*}}, i8* {{.*}}, <12 x i32> [[MT]])
  // CHECK-NEXT:    ret void

  m.value = __builtin_matrix_transpose(*r);
}

__attribute__((objc_root_class))
@interface PtrValue
@property unsigned *value;
@end

__attribute__((objc_root_class))
@interface IntValue
@property int value;
@end

void test_column_major_load(PtrValue *Ptr, IntValue *Stride) {
  // CHECK-LABEL: define{{.*}} void @test_column_major_load(%2* %Ptr, %3* %Stride) #4 {
  // CHECK:         [[STRIDE:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)
  // CHECK-NEXT:    [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64
  // CHECK:         [[PTR:%.*]] = call i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32* (i8*, i8*)*)
  // CHECK-NEXT:    call <12 x i32> @llvm.matrix.column.major.load.v12i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 3, i32 4)

  u3x4 m = __builtin_matrix_column_major_load(Ptr.value, 3, 4, Stride.value);
}

void test_column_major_store(UnsignedMatrixValue *M, PtrValue *Ptr, IntValue *Stride) {
  // CHECK-LABEL: define{{.*}} void @test_column_major_store(%1* %M, %2* %Ptr, %3* %Stride) #3 {
  // CHECK:         [[M:%.*]] = call <12 x i32> bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to <12 x i32> (i8*, i8*)*)
  // CHECK:         [[PTR:%.*]] = call i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32* (i8*, i8*)*)
  // CHECK:         [[IDX:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)
  // CHECK-NEXT:    [[IDX_EXT:%.*]] = sext i32 [[IDX]] to i64
  // CHECK-NEXT:    call void @llvm.matrix.column.major.store.v12i32(<12 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 3, i32 4)

  __builtin_matrix_column_major_store(M.value, Ptr.value, Stride.value);
}
