aqjune updated this revision to Diff 284246.
aqjune added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Update PR3589-freestanding-libcalls.c


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85345/new/

https://reviews.llvm.org/D85345

Files:
  clang/test/CodeGen/PR3589-freestanding-libcalls.c
  llvm/lib/Transforms/Utils/BuildLibCalls.cpp
  llvm/test/CodeGen/X86/no-plt-libcalls.ll
  llvm/test/Transforms/InferFunctionAttrs/annotate.ll

Index: llvm/test/Transforms/InferFunctionAttrs/annotate.ll
===================================================================
--- llvm/test/Transforms/InferFunctionAttrs/annotate.ll
+++ llvm/test/Transforms/InferFunctionAttrs/annotate.ll
@@ -352,19 +352,19 @@
 ; CHECK: declare x86_fp80 @fabsl(x86_fp80) [[G0]]
 declare x86_fp80 @fabsl(x86_fp80)
 
-; CHECK: declare i32 @fclose(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @fclose(%opaque* nocapture noundef) [[G1]]
 declare i32 @fclose(%opaque*)
 
-; CHECK: declare noalias %opaque* @fdopen(i32, i8* nocapture readonly) [[G1]]
+; CHECK: declare noalias noundef %opaque* @fdopen(i32 noundef, i8* nocapture noundef readonly) [[G1]]
 declare %opaque* @fdopen(i32, i8*)
 
-; CHECK: declare i32 @feof(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @feof(%opaque* nocapture noundef) [[G1]]
 declare i32 @feof(%opaque*)
 
-; CHECK: declare i32 @ferror(%opaque* nocapture) [[G2]]
+; CHECK: declare noundef i32 @ferror(%opaque* nocapture noundef) [[G2]]
 declare i32 @ferror(%opaque*)
 
-; CHECK: declare i32 @fflush(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @fflush(%opaque* nocapture noundef) [[G1]]
 declare i32 @fflush(%opaque*)
 
 ; CHECK: declare i32 @ffs(i32) [[G0]]
@@ -376,19 +376,19 @@
 ; CHECK: declare i32 @ffsll(i64) [[G0]]
 declare i32 @ffsll(i64)
 
-; CHECK: declare i32 @fgetc(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @fgetc(%opaque* nocapture noundef) [[G1]]
 declare i32 @fgetc(%opaque*)
 
-; CHECK: declare i32 @fgetpos(%opaque* nocapture, i64* nocapture) [[G1]]
+; CHECK: declare noundef i32 @fgetpos(%opaque* nocapture noundef, i64* nocapture noundef) [[G1]]
 declare i32 @fgetpos(%opaque*, i64*)
 
-; CHECK: declare i8* @fgets(i8*, i32, %opaque* nocapture) [[G1]]
+; CHECK: declare noundef i8* @fgets(i8* noundef, i32 noundef, %opaque* nocapture noundef) [[G1]]
 declare i8* @fgets(i8*, i32, %opaque*)
 
-; CHECK: declare i32 @fileno(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @fileno(%opaque* nocapture noundef) [[G1]]
 declare i32 @fileno(%opaque*)
 
-; CHECK: declare void @flockfile(%opaque* nocapture) [[G1]]
+; CHECK: declare void @flockfile(%opaque* nocapture noundef) [[G1]]
 declare void @flockfile(%opaque*)
 
 ; CHECK: declare double @floor(double) [[G0]]
@@ -436,19 +436,19 @@
 ; CHECK: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[G0]]
 declare x86_fp80 @fmodl(x86_fp80, x86_fp80)
 
-; CHECK: declare noalias %opaque* @fopen(i8* nocapture readonly, i8* nocapture readonly) [[G1]]
+; CHECK: declare noalias noundef %opaque* @fopen(i8* nocapture noundef readonly, i8* nocapture noundef readonly) [[G1]]
 declare %opaque* @fopen(i8*, i8*)
 
-; CHECK: declare i32 @fprintf(%opaque* nocapture, i8* nocapture readonly, ...) [[G1]]
+; CHECK: declare noundef i32 @fprintf(%opaque* nocapture noundef, i8* nocapture noundef readonly, ...) [[G1]]
 declare i32 @fprintf(%opaque*, i8*, ...)
 
-; CHECK: declare i32 @fputc(i32, %opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @fputc(i32 noundef, %opaque* nocapture noundef) [[G1]]
 declare i32 @fputc(i32, %opaque*)
 
-; CHECK: declare i32 @fputs(i8* nocapture readonly, %opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @fputs(i8* nocapture noundef readonly, %opaque* nocapture noundef) [[G1]]
 declare i32 @fputs(i8*, %opaque*)
 
-; CHECK: declare i64 @fread(i8* nocapture, i64, i64, %opaque* nocapture) [[G1]]
+; CHECK: declare noundef i64 @fread(i8* nocapture noundef, i64 noundef, i64 noundef, %opaque* nocapture noundef) [[G1]]
 declare i64 @fread(i8*, i64, i64, %opaque*)
 
 ; CHECK: declare void @free(i8* nocapture) [[G3:#[0-9]+]]
@@ -463,61 +463,61 @@
 ; CHECK: declare x86_fp80 @frexpl(x86_fp80, i32* nocapture) [[G1]]
 declare x86_fp80 @frexpl(x86_fp80, i32*)
 
-; CHECK: declare i32 @fscanf(%opaque* nocapture, i8* nocapture readonly, ...) [[G1]]
+; CHECK: declare noundef i32 @fscanf(%opaque* nocapture noundef, i8* nocapture noundef readonly, ...) [[G1]]
 declare i32 @fscanf(%opaque*, i8*, ...)
 
-; CHECK: declare i32 @fseek(%opaque* nocapture, i64, i32) [[G1]]
+; CHECK: declare noundef i32 @fseek(%opaque* nocapture noundef, i64 noundef, i32 noundef) [[G1]]
 declare i32 @fseek(%opaque*, i64, i32)
 
-; CHECK: declare i32 @fseeko(%opaque* nocapture, i64, i32) [[G1]]
+; CHECK: declare noundef i32 @fseeko(%opaque* nocapture noundef, i64 noundef, i32 noundef) [[G1]]
 declare i32 @fseeko(%opaque*, i64, i32)
 
-; CHECK-LINUX: declare i32 @fseeko64(%opaque* nocapture, i64, i32) [[G1]]
+; CHECK-LINUX: declare noundef i32 @fseeko64(%opaque* nocapture noundef, i64 noundef, i32 noundef) [[G1]]
 declare i32 @fseeko64(%opaque*, i64, i32)
 
-; CHECK: declare i32 @fsetpos(%opaque* nocapture, i64*) [[G1]]
+; CHECK: declare noundef i32 @fsetpos(%opaque* nocapture noundef, i64* noundef) [[G1]]
 declare i32 @fsetpos(%opaque*, i64*)
 
-; CHECK: declare i32 @fstat(i32, %opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @fstat(i32 noundef, %opaque* nocapture noundef) [[G1]]
 declare i32 @fstat(i32, %opaque*)
 
-; CHECK-LINUX: declare i32 @fstat64(i32, %opaque* nocapture) [[G1]]
+; CHECK-LINUX: declare noundef i32 @fstat64(i32 noundef, %opaque* nocapture noundef) [[G1]]
 declare i32 @fstat64(i32, %opaque*)
 
-; CHECK: declare i32 @fstatvfs(i32, %opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @fstatvfs(i32 noundef, %opaque* nocapture noundef) [[G1]]
 declare i32 @fstatvfs(i32, %opaque*)
 
-; CHECK-LINUX: declare i32 @fstatvfs64(i32, %opaque* nocapture) [[G1]]
+; CHECK-LINUX: declare noundef i32 @fstatvfs64(i32 noundef, %opaque* nocapture noundef) [[G1]]
 declare i32 @fstatvfs64(i32, %opaque*)
 
-; CHECK: declare i64 @ftell(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i64 @ftell(%opaque* nocapture noundef) [[G1]]
 declare i64 @ftell(%opaque*)
 
-; CHECK: declare i64 @ftello(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i64 @ftello(%opaque* nocapture noundef) [[G1]]
 declare i64 @ftello(%opaque*)
 
-; CHECK-LINUX: declare i64 @ftello64(%opaque* nocapture) [[G1]]
+; CHECK-LINUX: declare noundef i64 @ftello64(%opaque* nocapture noundef) [[G1]]
 declare i64 @ftello64(%opaque*)
 
-; CHECK: declare i32 @ftrylockfile(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @ftrylockfile(%opaque* nocapture noundef) [[G1]]
 declare i32 @ftrylockfile(%opaque*)
 
-; CHECK: declare void @funlockfile(%opaque* nocapture) [[G1]]
+; CHECK: declare void @funlockfile(%opaque* nocapture noundef) [[G1]]
 declare void @funlockfile(%opaque*)
 
-; CHECK: declare i64 @fwrite(i8* nocapture, i64, i64, %opaque* nocapture) [[G1]]
+; CHECK: declare noundef i64 @fwrite(i8* nocapture noundef, i64 noundef, i64 noundef, %opaque* nocapture noundef) [[G1]]
 declare i64 @fwrite(i8*, i64, i64, %opaque*)
 
-; CHECK: declare i32 @getc(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @getc(%opaque* nocapture noundef) [[G1]]
 declare i32 @getc(%opaque*)
 
-; CHECK: declare i32 @getc_unlocked(%opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @getc_unlocked(%opaque* nocapture noundef) [[G1]]
 declare i32 @getc_unlocked(%opaque*)
 
-; CHECK: declare i32 @getchar() [[G1]]
+; CHECK: declare noundef i32 @getchar() [[G1]]
 declare i32 @getchar()
 
-; CHECK: declare i32 @getchar_unlocked() [[G1]]
+; CHECK: declare noundef i32 @getchar_unlocked() [[G1]]
 declare i32 @getchar_unlocked()
 
 ; CHECK: declare i8* @getenv(i8* nocapture) [[G2]]
@@ -532,7 +532,7 @@
 ; CHECK: declare %opaque* @getpwnam(i8* nocapture readonly) [[G1]]
 declare %opaque* @getpwnam(i8*)
 
-; CHECK: declare i8* @gets(i8*) [[G1]]
+; CHECK: declare noundef i8* @gets(i8* noundef) [[G1]]
 declare i8* @gets(i8*)
 
 ; CHECK: declare i32 @gettimeofday(%opaque* nocapture, i8* nocapture) [[G1]]
@@ -664,10 +664,10 @@
 ; CHECK: declare x86_fp80 @nearbyintl(x86_fp80) [[G0]]
 declare x86_fp80 @nearbyintl(x86_fp80)
 
-; CHECK: declare i32 @open(i8* nocapture readonly, i32, ...) [[G0]]
+; CHECK: declare noundef i32 @open(i8* nocapture noundef readonly, i32 noundef, ...) [[G0]]
 declare i32 @open(i8*, i32, ...)
 
-; CHECK-LINUX: declare i32 @open64(i8* nocapture readonly, i32, ...) [[G0]]
+; CHECK-LINUX: declare noundef i32 @open64(i8* nocapture noundef readonly, i32 noundef, ...) [[G0]]
 declare i32 @open64(i8*, i32, ...)
 
 ; CHECK: declare noalias %opaque* @opendir(i8* nocapture readonly) [[G1]]
@@ -676,7 +676,7 @@
 ; CHECK: declare i32 @pclose(%opaque* nocapture) [[G1]]
 declare i32 @pclose(%opaque*)
 
-; CHECK: declare void @perror(i8* nocapture readonly) [[G1]]
+; CHECK: declare void @perror(i8* nocapture noundef readonly) [[G1]]
 declare void @perror(i8*)
 
 ; CHECK: declare noalias %opaque* @popen(i8* nocapture readonly, i8* nocapture readonly) [[G1]]
@@ -694,31 +694,31 @@
 ; CHECK: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[G0]]
 declare x86_fp80 @powl(x86_fp80, x86_fp80)
 
-; CHECK: declare i64 @pread(i32, i8* nocapture, i64, i64) [[G0]]
+; CHECK: declare noundef i64 @pread(i32 noundef, i8* nocapture noundef, i64 noundef, i64 noundef) [[G0]]
 declare i64 @pread(i32, i8*, i64, i64)
 
-; CHECK: declare i32 @printf(i8* nocapture readonly, ...) [[G1]]
+; CHECK: declare noundef i32 @printf(i8* nocapture noundef readonly, ...) [[G1]]
 declare i32 @printf(i8*, ...)
 
-; CHECK: declare i32 @putc(i32, %opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @putc(i32 noundef, %opaque* nocapture noundef) [[G1]]
 declare i32 @putc(i32, %opaque*)
 
-; CHECK: declare i32 @putchar(i32) [[G1]]
+; CHECK: declare noundef i32 @putchar(i32 noundef) [[G1]]
 declare i32 @putchar(i32)
 
-; CHECK: declare i32 @putchar_unlocked(i32) [[G1]]
+; CHECK: declare noundef i32 @putchar_unlocked(i32 noundef) [[G1]]
 declare i32 @putchar_unlocked(i32)
 
-; CHECK: declare i32 @puts(i8* nocapture readonly) [[G1]]
+; CHECK: declare noundef i32 @puts(i8* nocapture noundef readonly) [[G1]]
 declare i32 @puts(i8*)
 
-; CHECK: declare i64 @pwrite(i32, i8* nocapture readonly, i64, i64) [[G0]]
+; CHECK: declare noundef i64 @pwrite(i32 noundef, i8* nocapture noundef readonly, i64 noundef, i64 noundef) [[G0]]
 declare i64 @pwrite(i32, i8*, i64, i64)
 
 ; CHECK: declare void @qsort(i8*, i64, i64, i32 (i8*, i8*)* nocapture) [[G0]]
 declare void @qsort(i8*, i64, i64, i32 (i8*, i8*)*)
 
-; CHECK: declare i64 @read(i32, i8* nocapture, i64) [[G0]]
+; CHECK: declare noundef i64 @read(i32 noundef, i8* nocapture noundef, i64 noundef) [[G0]]
 declare i64 @read(i32, i8*, i64)
 
 ; CHECK: declare i64 @readlink(i8* nocapture readonly, i8* nocapture, i64) [[G1]]
@@ -739,7 +739,7 @@
 ; CHECK: declare i32 @rename(i8* nocapture readonly, i8* nocapture readonly) [[G1]]
 declare i32 @rename(i8*, i8*)
 
-; CHECK: declare void @rewind(%opaque* nocapture) [[G1]]
+; CHECK: declare void @rewind(%opaque* nocapture noundef) [[G1]]
 declare void @rewind(%opaque*)
 
 ; CHECK: declare double @rint(double) [[G0]]
@@ -763,7 +763,7 @@
 ; CHECK: declare x86_fp80 @roundl(x86_fp80) [[G0]]
 declare x86_fp80 @roundl(x86_fp80)
 
-; CHECK: declare i32 @scanf(i8* nocapture readonly, ...) [[G1]]
+; CHECK: declare noundef i32 @scanf(i8* nocapture noundef readonly, ...) [[G1]]
 declare i32 @scanf(i8*, ...)
 
 ; CHECK: declare void @setbuf(%opaque* nocapture, i8*) [[G1]]
@@ -793,10 +793,10 @@
 ; CHECK: declare x86_fp80 @sinl(x86_fp80) [[G0]]
 declare x86_fp80 @sinl(x86_fp80)
 
-; CHECK: declare i32 @snprintf(i8* noalias nocapture, i64, i8* nocapture readonly, ...) [[G1]]
+; CHECK: declare noundef i32 @snprintf(i8* noalias nocapture noundef, i64 noundef, i8* nocapture noundef readonly, ...) [[G1]]
 declare i32 @snprintf(i8*, i64, i8*, ...)
 
-; CHECK: declare i32 @sprintf(i8* noalias nocapture, i8* nocapture readonly, ...) [[G1]]
+; CHECK: declare noundef i32 @sprintf(i8* noalias nocapture noundef, i8* nocapture noundef readonly, ...) [[G1]]
 declare i32 @sprintf(i8*, i8*, ...)
 
 ; CHECK: declare double @sqrt(double) [[G0]]
@@ -808,7 +808,7 @@
 ; CHECK: declare x86_fp80 @sqrtl(x86_fp80) [[G0]]
 declare x86_fp80 @sqrtl(x86_fp80)
 
-; CHECK: declare i32 @sscanf(i8* nocapture readonly, i8* nocapture readonly, ...) [[G1]]
+; CHECK: declare noundef i32 @sscanf(i8* nocapture noundef readonly, i8* nocapture noundef readonly, ...) [[G1]]
 declare i32 @sscanf(i8*, i8*, ...)
 
 ; CHECK: declare i32 @stat(i8* nocapture readonly, %opaque* nocapture) [[G1]]
@@ -961,7 +961,7 @@
 ; CHECK: declare i32 @uname(%opaque* nocapture) [[G1]]
 declare i32 @uname(%opaque*)
 
-; CHECK: declare i32 @ungetc(i32, %opaque* nocapture) [[G1]]
+; CHECK: declare noundef i32 @ungetc(i32 noundef, %opaque* nocapture noundef) [[G1]]
 declare i32 @ungetc(i32, %opaque*)
 
 ; CHECK: declare i32 @unlink(i8* nocapture readonly) [[G1]]
@@ -979,28 +979,28 @@
 ; CHECK: declare noalias i8* @valloc(i64) [[G1]]
 declare i8* @valloc(i64)
 
-; CHECK: declare i32 @vfprintf(%opaque* nocapture, i8* nocapture readonly, %opaque*) [[G1]]
+; CHECK: declare noundef i32 @vfprintf(%opaque* nocapture noundef, i8* nocapture noundef readonly, %opaque* noundef) [[G1]]
 declare i32 @vfprintf(%opaque*, i8*, %opaque*)
 
-; CHECK: declare i32 @vfscanf(%opaque* nocapture, i8* nocapture readonly, %opaque*) [[G1]]
+; CHECK: declare noundef i32 @vfscanf(%opaque* nocapture noundef, i8* nocapture noundef readonly, %opaque* noundef) [[G1]]
 declare i32 @vfscanf(%opaque*, i8*, %opaque*)
 
-; CHECK: declare i32 @vprintf(i8* nocapture readonly, %opaque*) [[G1]]
+; CHECK: declare noundef i32 @vprintf(i8* nocapture noundef readonly, %opaque* noundef) [[G1]]
 declare i32 @vprintf(i8*, %opaque*)
 
-; CHECK: declare i32 @vscanf(i8* nocapture readonly, %opaque*) [[G1]]
+; CHECK: declare noundef i32 @vscanf(i8* nocapture noundef readonly, %opaque* noundef) [[G1]]
 declare i32 @vscanf(i8*, %opaque*)
 
-; CHECK: declare i32 @vsnprintf(i8* nocapture, i64, i8* nocapture readonly, %opaque*) [[G1]]
+; CHECK: declare noundef i32 @vsnprintf(i8* nocapture noundef, i64 noundef, i8* nocapture noundef readonly, %opaque* noundef) [[G1]]
 declare i32 @vsnprintf(i8*, i64, i8*, %opaque*)
 
-; CHECK: declare i32 @vsprintf(i8* nocapture, i8* nocapture readonly, %opaque*) [[G1]]
+; CHECK: declare noundef i32 @vsprintf(i8* nocapture noundef, i8* nocapture noundef readonly, %opaque* noundef) [[G1]]
 declare i32 @vsprintf(i8*, i8*, %opaque*)
 
-; CHECK: declare i32 @vsscanf(i8* nocapture readonly, i8* nocapture readonly, %opaque*) [[G1]]
+; CHECK: declare noundef i32 @vsscanf(i8* nocapture noundef readonly, i8* nocapture noundef readonly, %opaque* noundef) [[G1]]
 declare i32 @vsscanf(i8*, i8*, %opaque*)
 
-; CHECK: declare i64 @write(i32, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare noundef i64 @write(i32 noundef, i8* nocapture noundef readonly, i64 noundef) [[G0]]
 declare i64 @write(i32, i8*, i64)
 
 
Index: llvm/test/CodeGen/X86/no-plt-libcalls.ll
===================================================================
--- llvm/test/CodeGen/X86/no-plt-libcalls.ll
+++ llvm/test/CodeGen/X86/no-plt-libcalls.ll
@@ -17,7 +17,7 @@
 }
 
 ; CHECK: Function Attrs: nofree nounwind nonlazybind
-; CHECK-NEXT: declare i32 @puts(i8* nocapture readonly)
+; CHECK-NEXT: declare noundef i32 @puts(i8* nocapture noundef readonly)
 
 !llvm.module.flags = !{!0}
 !0 = !{i32 7, !"RtLibUseGOT", i32 1}
Index: llvm/lib/Transforms/Utils/BuildLibCalls.cpp
===================================================================
--- llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -37,6 +37,7 @@
 STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
 STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
 STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
+STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns");
 STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
 STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
 
@@ -104,6 +105,24 @@
   return true;
 }
 
+static bool setRetAndArgsNoUndef(Function &F) {
+  bool Changed = false;
+  if (!F.getReturnType()->isVoidTy() &&
+      !F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoUndef)) {
+    F.addAttribute(AttributeList::ReturnIndex, Attribute::NoUndef);
+    ++NumNoUndef;
+    Changed = true;
+  }
+  for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) {
+    if (!F.hasParamAttribute(ArgNo, Attribute::NoUndef)) {
+      F.addParamAttr(ArgNo, Attribute::NoUndef);
+      ++NumNoUndef;
+      Changed = true;
+    }
+  }
+  return Changed;
+}
+
 static bool setRetNonNull(Function &F) {
   assert(F.getReturnType()->isPointerTy() &&
          "nonnull applies only to pointers");
@@ -227,6 +246,7 @@
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_scanf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setOnlyReadsMemory(F, 0);
@@ -251,6 +271,7 @@
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_sscanf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 1);
@@ -258,6 +279,7 @@
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_sprintf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotAlias(F, 0);
@@ -265,6 +287,7 @@
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_snprintf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotAlias(F, 0);
@@ -347,9 +370,11 @@
     return Changed;
   case LibFunc_read:
     // May throw; "read" is a valid pthread cancellation point.
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotCapture(F, 1);
     return Changed;
   case LibFunc_rewind:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
@@ -375,6 +400,7 @@
     return Changed;
   case LibFunc_write:
     // May throw; "write" is a valid pthread cancellation point.
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotCapture(F, 1);
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
@@ -428,6 +454,7 @@
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_fopen:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     Changed |= setDoesNotCapture(F, 0);
@@ -436,13 +463,21 @@
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_fdopen:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     Changed |= setDoesNotCapture(F, 1);
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_feof:
+    Changed |= setRetAndArgsNoUndef(F);
+    Changed |= setDoesNotThrow(F);
+    Changed |= setDoesNotCapture(F, 0);
+    return Changed;
   case LibFunc_free:
+    Changed |= setDoesNotThrow(F);
+    Changed |= setDoesNotCapture(F, 0);
+    return Changed;
   case LibFunc_fseek:
   case LibFunc_ftell:
   case LibFunc_fgetc:
@@ -456,10 +491,12 @@
   case LibFunc_flockfile:
   case LibFunc_funlockfile:
   case LibFunc_ftrylockfile:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
   case LibFunc_ferror:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setOnlyReadsMemory(F);
@@ -467,26 +504,37 @@
   case LibFunc_fputc:
   case LibFunc_fputc_unlocked:
   case LibFunc_fstat:
+    Changed |= setRetAndArgsNoUndef(F);
+    Changed |= setDoesNotThrow(F);
+    Changed |= setDoesNotCapture(F, 1);
+    return Changed;
   case LibFunc_frexp:
   case LibFunc_frexpf:
   case LibFunc_frexpl:
+    Changed |= setDoesNotThrow(F);
+    Changed |= setDoesNotCapture(F, 1);
+    return Changed;
   case LibFunc_fstatvfs:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 1);
     return Changed;
   case LibFunc_fgets:
   case LibFunc_fgets_unlocked:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 2);
     return Changed;
   case LibFunc_fread:
   case LibFunc_fread_unlocked:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 3);
     return Changed;
   case LibFunc_fwrite:
   case LibFunc_fwrite_unlocked:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 3);
@@ -494,6 +542,7 @@
     return Changed;
   case LibFunc_fputs:
   case LibFunc_fputs_unlocked:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 1);
@@ -501,19 +550,29 @@
     return Changed;
   case LibFunc_fscanf:
   case LibFunc_fprintf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 1);
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_fgetpos:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 1);
     return Changed;
   case LibFunc_getc:
+    Changed |= setRetAndArgsNoUndef(F);
+    Changed |= setDoesNotThrow(F);
+    Changed |= setDoesNotCapture(F, 0);
+    return Changed;
   case LibFunc_getlogin_r:
+    Changed |= setDoesNotThrow(F);
+    Changed |= setDoesNotCapture(F, 0);
+    return Changed;
   case LibFunc_getc_unlocked:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
@@ -525,6 +584,7 @@
   case LibFunc_gets:
   case LibFunc_getchar:
   case LibFunc_getchar_unlocked:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     return Changed;
   case LibFunc_getitimer:
@@ -537,6 +597,7 @@
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_ungetc:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 1);
     return Changed;
@@ -564,27 +625,32 @@
     return Changed;
   case LibFunc_putc:
   case LibFunc_putc_unlocked:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 1);
     return Changed;
   case LibFunc_puts:
   case LibFunc_printf:
   case LibFunc_perror:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_pread:
     // May throw; "pread" is a valid pthread cancellation point.
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotCapture(F, 1);
     return Changed;
   case LibFunc_pwrite:
     // May throw; "pwrite" is a valid pthread cancellation point.
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotCapture(F, 1);
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_putchar:
   case LibFunc_putchar_unlocked:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     return Changed;
   case LibFunc_popen:
@@ -600,11 +666,13 @@
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
   case LibFunc_vscanf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_vsscanf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 1);
@@ -612,6 +680,7 @@
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_vfscanf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 1);
@@ -622,18 +691,21 @@
     Changed |= setRetDoesNotAlias(F);
     return Changed;
   case LibFunc_vprintf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_vfprintf:
   case LibFunc_vsprintf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 1);
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_vsnprintf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 2);
@@ -641,6 +713,7 @@
     return Changed;
   case LibFunc_open:
     // May throw; "open" is a valid pthread cancellation point.
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
@@ -693,14 +766,17 @@
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_under_IO_getc:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
   case LibFunc_under_IO_putc:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 1);
     return Changed;
   case LibFunc_dunder_isoc99_scanf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setOnlyReadsMemory(F, 0);
@@ -714,6 +790,7 @@
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_dunder_isoc99_sscanf:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setDoesNotCapture(F, 1);
@@ -721,6 +798,7 @@
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_fopen64:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     Changed |= setDoesNotCapture(F, 0);
@@ -730,6 +808,7 @@
     return Changed;
   case LibFunc_fseeko64:
   case LibFunc_ftello64:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
@@ -739,11 +818,13 @@
     return Changed;
   case LibFunc_fstat64:
   case LibFunc_fstatvfs64:
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 1);
     return Changed;
   case LibFunc_open64:
     // May throw; "open" is a valid pthread cancellation point.
+    Changed |= setRetAndArgsNoUndef(F);
     Changed |= setDoesNotCapture(F, 0);
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
Index: clang/test/CodeGen/PR3589-freestanding-libcalls.c
===================================================================
--- clang/test/CodeGen/PR3589-freestanding-libcalls.c
+++ clang/test/CodeGen/PR3589-freestanding-libcalls.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | grep 'declare i32 @printf' | count 1
-// RUN: %clang_cc1 -triple i386-unknown-unknown -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 1
-// RUN: %clang_cc1 -triple i386-unknown-unknown -ffreestanding -O2 -emit-llvm %s -o - | not grep 'declare i32 @puts'
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O2 -emit-llvm %s -o - | grep 'declare noundef i32 @puts' | count 1
+// RUN: %clang_cc1 -triple i386-unknown-unknown -ffreestanding -O2 -emit-llvm %s -o - | not grep 'declare noundef i32 @puts'
 
 int printf(const char *, ...);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to