From d67f31b2fdf74d999b8a0b298361daee3503c2f5 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan@cn.ibm.com>
Date: Tue, 23 May 2023 16:22:32 +0800
Subject: [PATCH 08/10] [Clang] Support more stdio builtins

Add more builtins for stdio functions as in GCC, along with their
mutations under IEEE float128 ABI.

Reviewed By: tuliom

Differential Revision: https://reviews.llvm.org/D150087

Gentoo-Component: clang
---
 clang/include/clang/Basic/Builtins.def        | 36 +++++++-----
 clang/lib/CodeGen/CGBuiltin.cpp               | 24 ++++++--
 .../CodeGen/PowerPC/ppc64-f128-builtins.c     | 57 +++++++++++++++++++
 3 files changed, 99 insertions(+), 18 deletions(-)

diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index 41f124556446..e6a89da1912c 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -551,7 +551,6 @@ BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nctE")
 BUILTIN(__builtin_bcmp, "ivC*vC*z", "FnE")
 BUILTIN(__builtin_bcopy, "vv*v*z", "n")
 BUILTIN(__builtin_bzero, "vv*z", "nF")
-BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:")
 BUILTIN(__builtin_free, "vv*", "nF")
 BUILTIN(__builtin_malloc, "v*z", "nF")
 BUILTIN(__builtin_memchr, "v*vC*iz", "nFE")
@@ -562,7 +561,6 @@ BUILTIN(__builtin_memmove, "v*v*vC*z", "nFE")
 BUILTIN(__builtin_mempcpy, "v*v*vC*z", "nF")
 BUILTIN(__builtin_memset, "v*v*iz", "nF")
 BUILTIN(__builtin_memset_inline, "vv*iIz", "n")
-BUILTIN(__builtin_printf, "icC*.", "Fp:0:")
 BUILTIN(__builtin_stpcpy, "c*c*cC*", "nF")
 BUILTIN(__builtin_stpncpy, "c*c*cC*z", "nF")
 BUILTIN(__builtin_strcasecmp, "icC*cC*", "nF")
@@ -599,10 +597,20 @@ BUILTIN(__builtin_setjmp, "iv**", "j")
 BUILTIN(__builtin_longjmp, "vv**i", "r")
 BUILTIN(__builtin_unwind_init, "v", "")
 BUILTIN(__builtin_eh_return_data_regno, "iIi", "ncE")
-BUILTIN(__builtin_snprintf, "ic*zcC*.", "nFp:2:")
-BUILTIN(__builtin_sprintf, "ic*cC*.", "nFP:1:")
-BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
-BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
+BUILTIN(__builtin_fprintf, "iP*RcC*R.", "nFp:1:")
+BUILTIN(__builtin_printf, "icC*R.", "nFp:0:")
+BUILTIN(__builtin_sprintf, "ic*RcC*R.", "nFp:1:")
+BUILTIN(__builtin_snprintf, "ic*RzcC*R.", "nFp:2:")
+BUILTIN(__builtin_vprintf, "icC*Ra", "nFP:0:")
+BUILTIN(__builtin_vfprintf, "iP*RcC*Ra", "nFP:1:")
+BUILTIN(__builtin_vsprintf, "ic*RcC*Ra", "nFP:1:")
+BUILTIN(__builtin_vsnprintf, "ic*RzcC*Ra", "nFP:2:")
+BUILTIN(__builtin_fscanf, "iP*RcC*R.", "Fs:1:")
+BUILTIN(__builtin_scanf, "icC*R.", "Fs:0:")
+BUILTIN(__builtin_sscanf, "icC*RcC*R.", "Fs:1:")
+BUILTIN(__builtin_vfscanf, "iP*RcC*Ra", "FS:1:")
+BUILTIN(__builtin_vscanf, "icC*Ra", "FS:0:")
+BUILTIN(__builtin_vsscanf, "icC*RcC*Ra", "FS:1:")
 BUILTIN(__builtin_thread_pointer, "v*", "nc")
 BUILTIN(__builtin_launder, "v*v*", "ntE")
 LANGBUILTIN(__builtin_is_constant_evaluated, "b", "nE", CXX_LANG)
@@ -631,14 +639,14 @@ BUILTIN(__builtin___strlcpy_chk, "zc*cC*zz", "nF")
 BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
 BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
 BUILTIN(__builtin___stpncpy_chk, "c*c*cC*zz", "nF")
-BUILTIN(__builtin___snprintf_chk, "ic*zizcC*.", "Fp:4:")
-BUILTIN(__builtin___sprintf_chk, "ic*izcC*.", "Fp:3:")
-BUILTIN(__builtin___vsnprintf_chk, "ic*zizcC*a", "FP:4:")
-BUILTIN(__builtin___vsprintf_chk, "ic*izcC*a", "FP:3:")
-BUILTIN(__builtin___fprintf_chk, "iP*icC*.", "Fp:2:")
-BUILTIN(__builtin___printf_chk, "iicC*.", "Fp:1:")
-BUILTIN(__builtin___vfprintf_chk, "iP*icC*a", "FP:2:")
-BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
+BUILTIN(__builtin___snprintf_chk, "ic*RzizcC*R.", "Fp:4:")
+BUILTIN(__builtin___sprintf_chk, "ic*RizcC*R.", "Fp:3:")
+BUILTIN(__builtin___vsnprintf_chk, "ic*RzizcC*Ra", "FP:4:")
+BUILTIN(__builtin___vsprintf_chk, "ic*RizcC*Ra", "FP:3:")
+BUILTIN(__builtin___fprintf_chk, "iP*RicC*R.", "Fp:2:")
+BUILTIN(__builtin___printf_chk, "iicC*R.", "Fp:1:")
+BUILTIN(__builtin___vfprintf_chk, "iP*RicC*Ra", "FP:2:")
+BUILTIN(__builtin___vprintf_chk, "iicC*Ra", "FP:1:")
 
 BUILTIN(__builtin_unpredictable, "LiLi"   , "nc")
 BUILTIN(__builtin_expect, "LiLiLi"   , "ncE")
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f72e04a425d9..cc3c5cc5028a 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -98,13 +98,29 @@ llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
 
   // TODO: This list should be expanded or refactored after all GCC-compatible
   // std libcall builtins are implemented.
-  static SmallDenseMap<unsigned, StringRef, 8> F128Builtins{
+  static SmallDenseMap<unsigned, StringRef, 64> F128Builtins{
+      {Builtin::BI__builtin___fprintf_chk, "__fprintf_chkieee128"},
+      {Builtin::BI__builtin___printf_chk, "__printf_chkieee128"},
+      {Builtin::BI__builtin___snprintf_chk, "__snprintf_chkieee128"},
+      {Builtin::BI__builtin___sprintf_chk, "__sprintf_chkieee128"},
+      {Builtin::BI__builtin___vfprintf_chk, "__vfprintf_chkieee128"},
+      {Builtin::BI__builtin___vprintf_chk, "__vprintf_chkieee128"},
+      {Builtin::BI__builtin___vsnprintf_chk, "__vsnprintf_chkieee128"},
+      {Builtin::BI__builtin___vsprintf_chk, "__vsprintf_chkieee128"},
+      {Builtin::BI__builtin_fprintf, "__fprintfieee128"},
       {Builtin::BI__builtin_printf, "__printfieee128"},
+      {Builtin::BI__builtin_snprintf, "__snprintfieee128"},
+      {Builtin::BI__builtin_sprintf, "__sprintfieee128"},
+      {Builtin::BI__builtin_vfprintf, "__vfprintfieee128"},
+      {Builtin::BI__builtin_vprintf, "__vprintfieee128"},
       {Builtin::BI__builtin_vsnprintf, "__vsnprintfieee128"},
       {Builtin::BI__builtin_vsprintf, "__vsprintfieee128"},
-      {Builtin::BI__builtin_sprintf, "__sprintfieee128"},
-      {Builtin::BI__builtin_snprintf, "__snprintfieee128"},
-      {Builtin::BI__builtin_fprintf, "__fprintfieee128"},
+      {Builtin::BI__builtin_fscanf, "__fscanfieee128"},
+      {Builtin::BI__builtin_scanf, "__scanfieee128"},
+      {Builtin::BI__builtin_sscanf, "__sscanfieee128"},
+      {Builtin::BI__builtin_vfscanf, "__vfscanfieee128"},
+      {Builtin::BI__builtin_vscanf, "__vscanfieee128"},
+      {Builtin::BI__builtin_vsscanf, "__vsscanfieee128"},
       {Builtin::BI__builtin_nexttowardf128, "__nexttowardieee128"},
   };
 
diff --git a/clang/test/CodeGen/PowerPC/ppc64-f128-builtins.c b/clang/test/CodeGen/PowerPC/ppc64-f128-builtins.c
index 635e7fadbbf0..b7e6cc9a2eb4 100644
--- a/test/CodeGen/PowerPC/ppc64-f128-builtins.c
+++ b/test/CodeGen/PowerPC/ppc64-f128-builtins.c
@@ -52,6 +52,63 @@ void test_snprintf(void) {
   __builtin_snprintf(buf, 20, "%.Lf", x);
 }
 
+// IEEE128-LABEL: define dso_local void @test_scanf
+// IEEE128: call signext i32 (ptr, ...) @__scanfieee128
+// PPC128-LABEL: define dso_local void @test_scanf
+// PPC128: call signext i32 (ptr, ...) @scanf
+void test_scanf(int *x) {
+  __builtin_scanf("%d", x);
+}
+
+// IEEE128-LABEL: define dso_local void @test_sscanf
+// IEEE128: call signext i32 (ptr, ptr, ...) @__sscanfieee128
+// PPC128-LABEL: define dso_local void @test_sscanf
+// PPC128: call signext i32 (ptr, ptr, ...) @sscanf
+void test_sscanf(int *x) {
+  __builtin_sscanf(buf, "%d", x);
+}
+
+// IEEE128-LABEL: define dso_local void @test_vprintf
+// IEEE128: call signext i32 @__vprintfieee128
+// PPC128-LABEL: define dso_local void @test_vprintf
+// PPC128: call signext i32 @vprintf
+void test_vprintf(const char *fmt, ...) {
+  __builtin_va_list args;
+  __builtin_va_start(args, fmt);
+  __builtin_vprintf(fmt, args);
+  __builtin_va_end(args);
+}
+
+// IEEE128-LABEL: define dso_local void @test_vscanf
+// IEEE128: call signext i32 @__vscanfieee128
+// PPC128-LABEL: define dso_local void @test_vscanf
+// PPC128: call signext i32 @vscanf
+void test_vscanf(const char *fmt, ...) {
+  __builtin_va_list args;
+  __builtin_va_start(args, fmt);
+  __builtin_vscanf(fmt, args);
+  __builtin_va_end(args);
+}
+
+// IEEE128-LABEL: define dso_local void @test_vsscanf
+// IEEE128: call signext i32 @__vsscanfieee128
+// PPC128-LABEL: define dso_local void @test_vsscanf
+// PPC128: call signext i32 @vsscanf
+void test_vsscanf(const char *fmt, ...) {
+  __builtin_va_list args;
+  __builtin_va_start(args, fmt);
+  __builtin_vsscanf(buf, fmt, args);
+  __builtin_va_end(args);
+}
+
+// IEEE128-LABEL: define dso_local void @test_snprintf_chk
+// IEEE128: call signext i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chkieee128
+// PPC128-LABEL: define dso_local void @test_snprintf_chk
+// PPC128: call signext i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk
+void test_snprintf_chk(long double x) {
+  __builtin___snprintf_chk(buf, 20, 1, 20, "%.Lf", x);
+}
+
 // GLIBC has special handling of 'nexttoward'
 
 // IEEE128-LABEL: define dso_local fp128 @test_nexttoward
-- 
2.41.0

