diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2087,6 +2087,12 @@ Address FieldAddress = Address(FieldPtr, Align); FieldPtr = CGF.Builder.CreateLoad(FieldAddress); + // Variadic functions expect the caller to promote float to double. + if (CanonicalType == Context.FloatTy) { + FieldPtr = + CGF.Builder.CreateFPExt(FieldPtr, CGF.ConvertType(Context.DoubleTy)); + } + // FIXME Need to handle bitfield here GString = CGF.Builder.CreateGlobalStringPtr( Format.concat(llvm::Twine('\n')).str()); diff --git a/clang/test/CodeGen/dump-struct-builtin.c b/clang/test/CodeGen/dump-struct-builtin.c --- a/clang/test/CodeGen/dump-struct-builtin.c +++ b/clang/test/CodeGen/dump-struct-builtin.c @@ -113,6 +113,12 @@ // CHECK-NEXT: [[FORMAT_U18:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%Lf\0A\00" // CHECK-NEXT: [[END_STRUCT_U18:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00" +// CHECK: @__const.unit19.a = private unnamed_addr constant %struct.U19A { float 0x3FF1F9AD00000000 }, align 4 +// CHECK-NEXT: [[STRUCT_STR_U19:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U19A {\0A\00" +// CHECK-NEXT: [[FIELD_U19:@[0-9]+]] = private unnamed_addr constant [11 x i8] c"float a : \00" +// CHECK-NEXT: [[FORMAT_U19:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%f\0A\00" +// CHECK-NEXT: [[END_STRUCT_U19:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00" + int printf(const char *fmt, ...) { return 0; } @@ -553,3 +559,22 @@ // CHECK: call i32 (i8*, ...) @printf( __builtin_dump_struct(&a, &printf); } + +void unit19() { + struct U19A { + float a; + }; + + struct U19A a = { + .a = 1.123456f, + }; + + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U19]], i32 0, i32 0)) + // CHECK: [[RES1:%[0-9]+]] = getelementptr inbounds %struct.U19A, %struct.U19A* %a, i32 0, i32 0 + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[FIELD_U19]], i32 0, i32 0)) + // CHECK: [[LOAD1:%[0-9]+]] = load float, float* [[RES1]], + // CHECK: [[FPEXT1:%[0-9]+]] = fpext float [[LOAD1]] to double + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U19]], i32 0, i32 0), double [[FPEXT1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U19]], i32 0, i32 0) + __builtin_dump_struct(&a, &printf); +}