https://github.com/nikic created 
https://github.com/llvm/llvm-project/pull/232729

This stops emitting the zeroext/signext attributes for return values on X86, 
except for `bool` (which stays zeroext, as it requires zero-extension to 8 
bits) and Darwin.

The `getTypeForExtReturn()` in the X86 backend already ignores zeroext/signext 
for i8 and i16 types on non-Darwin platforms. For these cases, this change has 
no impact on codegen: The intent is merely to clarify the used psABI. Using 
zeroext/signext when no actual extension takes place is highly confusing, esp. 
when the behavior is different between return values and arguments.

However, this *does* change behavior for non-i8/i16 types. Specifically, it 
changes `_BitInt` types to have unspecified high bits, instead of performing a 
partial sign/zero extension to 8, 16 or 32 bits. This makes `_BitInt` comply 
with the Linux psABI, the previous behavior was incorrect. MSVC does not 
support `_BitInt`, so there is no correct ABI there.

Because the only case with actual behavior change is `_BitInt`, I'm not 
bothering with `-fclang-abi-compat` for this change. We explicitly document 
`_BitInt` as not ABI stable at this point.

This change does not affect handling of arguments.

>From 4c4734d685943adcc6995cf9687982bcf20d8a34 Mon Sep 17 00:00:00 2001
From: Nikita Popov <[email protected]>
Date: Wed, 14 Oct 2026 14:39:53 +0200
Subject: [PATCH] [Clang][ABI][X86] Do not emit zeroext/signext for return
 values

This stops emitting the zeroext/signext attributes for return values
on X86, except for `bool` (which stays zeroext) and Darwin.

The `getTypeForExtReturn()` in the X86 backend already ignores
zeroext/signext for i8 and i16 types on non-Darwin platforms. For
these cases, this change has no impact on codegen: The intent is
merely to clarify the used psABI. Using zeroext/signext when no
actual extension takes place is highly confusing, esp. when the
behavior is different between return values and arguments.

However, this *does* change behavior for non-i8/i16 types.
Specifically, it changes `_BitInt` types to have unspecified
high bits, instead of performing a partial sign/zero extension to
8, 16 or 32 bits. This makes `_BitInt` comply with the Linux psABI,
the previous behavior was incorrect. MSVC does not support `_BitInt`,
so there is no correct ABI there.

Because the only case with actual behavior change is `_BitInt`,
I'm not bothering with `-fclang-abi-compat` for this change. We
explicitly document `_BitInt` as not ABI stable at this point.

This change does not affect handling of arguments.
---
 clang/lib/CodeGen/Targets/X86.cpp             | 24 +++++++--
 clang/test/C/C2y/n3254.c                      |  4 +-
 clang/test/CodeGen/X86/ms-x86-intrinsics.c    |  4 +-
 clang/test/CodeGen/X86/x86_64-arguments.c     |  6 +--
 clang/test/CodeGen/attr-noundef.cpp           |  2 +-
 .../test/CodeGen/attr-sized-by-for-pointers.c | 24 ++++-----
 .../attr-sized-by-or-null-for-pointers.c      | 24 ++++-----
 clang/test/CodeGen/function-attributes.c      |  8 +--
 .../test/CodeGen/overflow-behavior-types.cpp  |  2 +-
 .../test/CodeGenCXX/cxx20-consteval-crash.cpp |  6 +--
 clang/test/CodeGenCXX/ext-int.cpp             |  4 +-
 .../test/CodeGenCXX/ms-inline-asm-return.cpp  |  4 +-
 clang/test/CodeGenCXX/pr12251.cpp             |  2 +-
 clang/test/CodeGenObjC/property.m             |  6 +--
 clang/test/DebugInfo/CXX/ptr-to-ptr.cpp       |  4 +-
 ...ibute_parallel_for_num_threads_codegen.cpp |  8 +--
 ..._parallel_for_simd_num_threads_codegen.cpp | 10 ++--
 llvm/lib/ABI/Targets/X86.cpp                  | 23 +++++++--
 llvm/unittests/ABI/X86TargetInfoTest.cpp      | 49 +++++++++++++++++++
 19 files changed, 146 insertions(+), 68 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/X86.cpp 
b/clang/lib/CodeGen/Targets/X86.cpp
index c0947c481d2b07..eed851b306ad49 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -459,6 +459,18 @@ bool X86_32ABIInfo::canExpandIndirectArgument(QualType Ty) 
const {
   return Size == getContext().getTypeSize(Ty);
 }
 
+static bool shouldExtendReturnType(const ABIInfo &Info, QualType RetTy) {
+  // Bools need to be zero-extended to 8 bits for all ABIs.
+  if (RetTy->isBooleanType())
+    return true;
+
+  // Promotable integer types get extended only for Darwin.
+  if (!Info.getTarget().getTriple().isOSDarwin())
+    return false;
+
+  return Info.isPromotableIntegerTypeForABI(RetTy);
+}
+
 ABIArgInfo X86_32ABIInfo::getIndirectReturnResult(QualType RetTy, CCState 
&State) const {
   // If the return value is indirect, then the hidden argument is consuming one
   // integer register.
@@ -565,8 +577,8 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
     if (EIT->getNumBits() > 64)
       return getIndirectReturnResult(RetTy, State);
 
-  return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
-                                               : ABIArgInfo::getDirect());
+  return shouldExtendReturnType(*this, RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                              : ABIArgInfo::getDirect();
 }
 
 unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty,
@@ -2385,8 +2397,8 @@ ABIArgInfo 
X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const {
       return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
 
     llvm::Type *IRTy = CGT.ConvertType(Ty);
-    return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, IRTy)
-                                              : ABIArgInfo::getDirect(IRTy));
+    return shouldExtendReturnType(*this, Ty) ? ABIArgInfo::getExtend(Ty, IRTy)
+                                             : ABIArgInfo::getDirect(IRTy);
   }
 
   return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
@@ -2838,7 +2850,9 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType 
RetTy) const {
 
       if (RetTy->isIntegralOrEnumerationType() &&
           isPromotableIntegerTypeForABI(RetTy))
-        return ABIArgInfo::getExtend(RetTy);
+        return shouldExtendReturnType(*this, RetTy)
+                   ? ABIArgInfo::getExtend(RetTy)
+                   : ABIArgInfo::getDirect();
     }
 
     if (ResType->isIntegerTy(128)) {
diff --git a/clang/test/C/C2y/n3254.c b/clang/test/C/C2y/n3254.c
index 9f8c47756df328..c83217559a704c 100644
--- a/clang/test/C/C2y/n3254.c
+++ b/clang/test/C/C2y/n3254.c
@@ -37,7 +37,7 @@ int foo() {
   return s_ptr->x;
 }
 
-// CHECK-LABEL: define dso_local signext i8 @bar(
+// CHECK-LABEL: define dso_local i8 @bar(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 4
@@ -77,7 +77,7 @@ struct T {
   DECL_BUFFER(struct S, buffer);
 };
 
-// CHECK-LABEL: define dso_local signext i8 @quux(
+// CHECK-LABEL: define dso_local i8 @quux(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[T:%.*]] = alloca [[STRUCT_T:%.*]], align 4
diff --git a/clang/test/CodeGen/X86/ms-x86-intrinsics.c 
b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
index 9099b56e50d45e..803444df852278 100644
--- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c
+++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
@@ -11,7 +11,7 @@
 char test__readfsbyte(unsigned long Offset) {
   return __readfsbyte(++Offset);
 }
-// CHECK-I386-LABEL: define dso_local signext i8 @test__readfsbyte(i32 noundef 
%Offset)
+// CHECK-I386-LABEL: define dso_local i8 @test__readfsbyte(i32 noundef %Offset)
 // CHECK-I386:   %inc = add i32 %Offset, 1
 // CHECK-I386:   [[PTR:%[0-9]+]] = inttoptr i32 %inc to ptr addrspace(257)
 // CHECK-I386:   [[VALUE:%[0-9]+]] = load volatile i8, ptr addrspace(257) 
[[PTR]], align 1
@@ -20,7 +20,7 @@ char test__readfsbyte(unsigned long Offset) {
 short test__readfsword(unsigned long Offset) {
   return __readfsword(++Offset);
 }
-// CHECK-I386-LABEL: define dso_local signext i16 @test__readfsword(i32 
noundef %Offset)
+// CHECK-I386-LABEL: define dso_local i16 @test__readfsword(i32 noundef 
%Offset)
 // CHECK-I386:   %inc = add i32 %Offset, 1
 // CHECK-I386:   [[PTR:%[0-9]+]] = inttoptr i32 %inc to ptr addrspace(257)
 // CHECK-I386:   [[VALUE:%[0-9]+]] = load volatile i16, ptr addrspace(257) 
[[PTR]], align 2
diff --git a/clang/test/CodeGen/X86/x86_64-arguments.c 
b/clang/test/CodeGen/X86/x86_64-arguments.c
index b56792dd50cddd..73f99b9a814b4e 100644
--- a/clang/test/CodeGen/X86/x86_64-arguments.c
+++ b/clang/test/CodeGen/X86/x86_64-arguments.c
@@ -6,17 +6,17 @@
 // RUN:   FileCheck %s -check-prefix=CHECK -check-prefix=AVX 
-check-prefix=AVX512
 #include <stdarg.h>
 
-// CHECK-LABEL: define{{.*}} signext i8 @f0()
+// CHECK-LABEL: define dso_local i8 @f0()
 char f0(void) {
   return 0;
 }
 
-// CHECK-LABEL: define{{.*}} signext i16 @f1()
+// CHECK-LABEL: define dso_local i16 @f1()
 short f1(void) {
   return 0;
 }
 
-// CHECK-LABEL: define{{.*}} i32 @f2()
+// CHECK-LABEL: define dso_local i32 @f2()
 int f2(void) {
   return 0;
 }
diff --git a/clang/test/CodeGen/attr-noundef.cpp 
b/clang/test/CodeGen/attr-noundef.cpp
index 582743a5be5fa6..9b14381d004b84 100644
--- a/clang/test/CodeGen/attr-noundef.cpp
+++ b/clang/test/CodeGen/attr-noundef.cpp
@@ -158,7 +158,7 @@ void pass_large_BitInt(_BitInt(127) e) {
 // CHECK: [[DEF]] ptr @{{.*}}ret_npt{{.*}}()
 // CHECK: [[DEF]] void @{{.*}}pass_npt{{.*}}(ptr %
 
-// CHECK-INTEL: [[DEF]] noundef signext i3 @{{.*}}ret_BitInt{{.*}}()
+// CHECK-INTEL: [[DEF]] noundef i3 @{{.*}}ret_BitInt{{.*}}()
 // CHECK-AARCH: [[DEF]] noundef i3 @{{.*}}ret_BitInt{{.*}}()
 // CHECK-INTEL: [[DEF]] void @{{.*}}pass_BitInt{{.*}}(i3 noundef signext %
 // CHECK-AARCH: [[DEF]] void @{{.*}}pass_BitInt{{.*}}(i3 noundef %
diff --git a/clang/test/CodeGen/attr-sized-by-for-pointers.c 
b/clang/test/CodeGen/attr-sized-by-for-pointers.c
index dabe3163571a5d..a3293689027969 100644
--- a/clang/test/CodeGen/attr-sized-by-for-pointers.c
+++ b/clang/test/CodeGen/attr-sized-by-for-pointers.c
@@ -210,7 +210,7 @@ struct annotated_sized_ptr_odd_pointee {
   unsigned byte_count;
 };
 
-// SANITIZE-WITH-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_odd_pointee(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local i8 
@test_load_subscript_odd_pointee(
 // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
 // SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITH-ATTR-NEXT:    [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr 
inbounds nuw i8, ptr [[P]], i64 16
@@ -230,7 +230,7 @@ struct annotated_sized_ptr_odd_pointee {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP4:%.*]] = load i8, ptr [[ARRAYIDX]], align 
1, !tbaa [[CHAR_TBAA19:![0-9]+]]
 // SANITIZE-WITH-ATTR-NEXT:    ret i8 [[TMP4]]
 //
-// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_odd_pointee(
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i8 
@test_load_subscript_odd_pointee(
 // NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
 // NO-SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[BUF:%.*]] = getelementptr inbounds nuw i8, 
ptr [[P]], i64 8
@@ -240,7 +240,7 @@ struct annotated_sized_ptr_odd_pointee {
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17:![0-9]+]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_odd_pointee(
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_odd_pointee(
 // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef 
[[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
 // SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[BUF:%.*]] = getelementptr inbounds nuw i8, 
ptr [[P]], i64 8
@@ -250,7 +250,7 @@ struct annotated_sized_ptr_odd_pointee {
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17:![0-9]+]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_odd_pointee(
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_odd_pointee(
 // NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[BUF:%.*]] = getelementptr inbounds nuw 
i8, ptr [[P]], i64 8
@@ -341,14 +341,14 @@ struct annotated_sized_ptr_narrow_unsigned_count {
   unsigned char byte_count;
 };
 
-// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef signext i8 
@test_load_subscript_narrow_unsigned_count(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i8 
@test_load_subscript_narrow_unsigned_count(
 // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) 
local_unnamed_addr #[[ATTR2:[0-9]+]] {
 // SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = zext i32 [[INDEX]] to i64, 
!nosanitize [[META6]]
 // SANITIZE-WITH-ATTR-NEXT:    tail call void 
@__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 
[[TMP0]]) #[[ATTR6]], !nosanitize [[META6]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META6]]
 //
-// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_unsigned_count(
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_unsigned_count(
 // NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
 // NO-SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, 
!tbaa [[_ZTS13LARGE_POINTEEPTR_TBAA20:![0-9]+]]
@@ -357,7 +357,7 @@ struct annotated_sized_ptr_narrow_unsigned_count {
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_unsigned_count(
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_unsigned_count(
 // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef 
[[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
 // SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, 
!tbaa [[_ZTS13LARGE_POINTEEPTR_TBAA20:![0-9]+]]
@@ -366,7 +366,7 @@ struct annotated_sized_ptr_narrow_unsigned_count {
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_unsigned_count(
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_unsigned_count(
 // NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 
8, !tbaa [[_ZTS13LARGE_POINTEEPTR_TBAA20:![0-9]+]]
@@ -388,14 +388,14 @@ struct annotated_sized_ptr_narrow_signed_count {
   signed char byte_count;
 };
 
-// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef signext i8 
@test_load_subscript_narrow_signed_count(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i8 
@test_load_subscript_narrow_signed_count(
 // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) 
local_unnamed_addr #[[ATTR2]] {
 // SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = zext i32 [[INDEX]] to i64, 
!nosanitize [[META6]]
 // SANITIZE-WITH-ATTR-NEXT:    tail call void 
@__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 
[[TMP0]]) #[[ATTR6]], !nosanitize [[META6]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META6]]
 //
-// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_signed_count(
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_signed_count(
 // NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
 // NO-SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, 
!tbaa [[_ZTS15MIDSIZE_POINTEEPTR_TBAA23:![0-9]+]]
@@ -404,7 +404,7 @@ struct annotated_sized_ptr_narrow_signed_count {
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_signed_count(
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_signed_count(
 // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef 
[[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
 // SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, 
!tbaa [[_ZTS15MIDSIZE_POINTEEPTR_TBAA23:![0-9]+]]
@@ -413,7 +413,7 @@ struct annotated_sized_ptr_narrow_signed_count {
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_signed_count(
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_signed_count(
 // NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 
8, !tbaa [[_ZTS15MIDSIZE_POINTEEPTR_TBAA23:![0-9]+]]
diff --git a/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c 
b/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c
index 05f3c57d861498..afe97592b9f7a1 100644
--- a/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c
+++ b/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c
@@ -222,7 +222,7 @@ struct annotated_sized_ptr_odd_pointee {
   unsigned byte_count;
 };
 
-// SANITIZE-WITH-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_odd_pointee(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local i8 
@test_load_subscript_odd_pointee(
 // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
 // SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITH-ATTR-NEXT:    [[BUF:%.*]] = getelementptr inbounds nuw i8, 
ptr [[P]], i64 8
@@ -244,7 +244,7 @@ struct annotated_sized_ptr_odd_pointee {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP6:%.*]] = load i8, ptr [[ARRAYIDX]], align 
1, !tbaa [[CHAR_TBAA19:![0-9]+]]
 // SANITIZE-WITH-ATTR-NEXT:    ret i8 [[TMP6]]
 //
-// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_odd_pointee(
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i8 
@test_load_subscript_odd_pointee(
 // NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
 // NO-SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[BUF:%.*]] = getelementptr inbounds nuw i8, 
ptr [[P]], i64 8
@@ -254,7 +254,7 @@ struct annotated_sized_ptr_odd_pointee {
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17:![0-9]+]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_odd_pointee(
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_odd_pointee(
 // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef 
[[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
 // SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[BUF:%.*]] = getelementptr inbounds nuw i8, 
ptr [[P]], i64 8
@@ -264,7 +264,7 @@ struct annotated_sized_ptr_odd_pointee {
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17:![0-9]+]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_odd_pointee(
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_odd_pointee(
 // NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[BUF:%.*]] = getelementptr inbounds nuw 
i8, ptr [[P]], i64 8
@@ -357,14 +357,14 @@ struct annotated_sized_ptr_narrow_unsigned_count {
   unsigned char byte_count;
 };
 
-// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef signext i8 
@test_load_subscript_narrow_unsigned_count(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i8 
@test_load_subscript_narrow_unsigned_count(
 // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) 
local_unnamed_addr #[[ATTR2:[0-9]+]] {
 // SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = zext i32 [[INDEX]] to i64, 
!nosanitize [[META12]]
 // SANITIZE-WITH-ATTR-NEXT:    tail call void 
@__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 
[[TMP0]]) #[[ATTR6]], !nosanitize [[META12]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META12]]
 //
-// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_unsigned_count(
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_unsigned_count(
 // NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
 // NO-SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, 
!tbaa [[_ZTS13LARGE_POINTEEPTR_TBAA20:![0-9]+]]
@@ -373,7 +373,7 @@ struct annotated_sized_ptr_narrow_unsigned_count {
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_unsigned_count(
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_unsigned_count(
 // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef 
[[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
 // SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, 
!tbaa [[_ZTS13LARGE_POINTEEPTR_TBAA20:![0-9]+]]
@@ -382,7 +382,7 @@ struct annotated_sized_ptr_narrow_unsigned_count {
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_unsigned_count(
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_unsigned_count(
 // NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 
8, !tbaa [[_ZTS13LARGE_POINTEEPTR_TBAA20:![0-9]+]]
@@ -404,14 +404,14 @@ struct annotated_sized_ptr_narrow_signed_count {
   signed char byte_count;
 };
 
-// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef signext i8 
@test_load_subscript_narrow_signed_count(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i8 
@test_load_subscript_narrow_signed_count(
 // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) 
local_unnamed_addr #[[ATTR2]] {
 // SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = zext i32 [[INDEX]] to i64, 
!nosanitize [[META12]]
 // SANITIZE-WITH-ATTR-NEXT:    tail call void 
@__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 
[[TMP0]]) #[[ATTR6]], !nosanitize [[META12]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META12]]
 //
-// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_signed_count(
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_signed_count(
 // NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
 // NO-SANITIZE-WITH-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, 
!tbaa [[_ZTS15MIDSIZE_POINTEEPTR_TBAA23:![0-9]+]]
@@ -420,7 +420,7 @@ struct annotated_sized_ptr_narrow_signed_count {
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_signed_count(
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_signed_count(
 // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef 
[[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
 // SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, 
!tbaa [[_ZTS15MIDSIZE_POINTEEPTR_TBAA23:![0-9]+]]
@@ -429,7 +429,7 @@ struct annotated_sized_ptr_narrow_signed_count {
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], 
align 1, !tbaa [[CHAR_TBAA17]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    ret i8 [[TMP1]]
 //
-// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local signext i8 
@test_load_subscript_narrow_signed_count(
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i8 
@test_load_subscript_narrow_signed_count(
 // NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) 
[[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:  [[ENTRY:.*:]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[P]], align 
8, !tbaa [[_ZTS15MIDSIZE_POINTEEPTR_TBAA23:![0-9]+]]
diff --git a/clang/test/CodeGen/function-attributes.c 
b/clang/test/CodeGen/function-attributes.c
index bb8670a8530e09..b55cdb1606e441 100644
--- a/clang/test/CodeGen/function-attributes.c
+++ b/clang/test/CodeGen/function-attributes.c
@@ -1,12 +1,12 @@
 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm 
-disable-llvm-passes -Os -o - %s | FileCheck %s
 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm 
-disable-llvm-passes -Os -std=c99 -o - %s | FileCheck %s
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm 
-disable-llvm-passes -Os -std=c99 -o - %s | FileCheck %s
-// CHECK: define{{.*}} signext i8 @f0(i32 noundef %x) [[NUW:#[0-9]+]]
-// CHECK: define{{.*}} zeroext i8 @f1(i32 noundef %x) [[NUW]]
+// CHECK: define{{.*}} i8 @f0(i32 noundef %x) [[NUW:#[0-9]+]]
+// CHECK: define{{.*}} i8 @f1(i32 noundef %x) [[NUW]]
 // CHECK: define{{.*}} void @f2(i8 noundef signext %x) [[NUW]]
 // CHECK: define{{.*}} void @f3(i8 noundef zeroext %x) [[NUW]]
-// CHECK: define{{.*}} signext i16 @f4(i32 noundef %x) [[NUW]]
-// CHECK: define{{.*}} zeroext i16 @f5(i32 noundef %x) [[NUW]]
+// CHECK: define{{.*}} i16 @f4(i32 noundef %x) [[NUW]]
+// CHECK: define{{.*}} i16 @f5(i32 noundef %x) [[NUW]]
 // CHECK: define{{.*}} void @f6(i16 noundef signext %x) [[NUW]]
 // CHECK: define{{.*}} void @f7(i16 noundef zeroext %x) [[NUW]]
 
diff --git a/clang/test/CodeGen/overflow-behavior-types.cpp 
b/clang/test/CodeGen/overflow-behavior-types.cpp
index 89d9d5b24cf09e..2ab535e82b2e00 100644
--- a/clang/test/CodeGen/overflow-behavior-types.cpp
+++ b/clang/test/CodeGen/overflow-behavior-types.cpp
@@ -26,7 +26,7 @@ void test_members(char some) {
   // DEFAULT-NEXT: %inc{{\d*}} = add i32 %[[CONV]], 1
   (++foo.a);
 
-  // DEFAULT: %[[CALL:.*]] = call noundef signext i8 @_ZNK3Foo4getAEv
+  // DEFAULT: %[[CALL:.*]] = call noundef i8 @_ZNK3Foo4getAEv
   // DEFAULT-NEXT: sext i8 %[[CALL]] to i32
   // DEFAULT-NEXT: add i32 {{.*}}, 1
   (void)(foo.getA() + 1);
diff --git a/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp 
b/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp
index 9c9324f428bec5..d06ed9a649cc8c 100644
--- a/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp
+++ b/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp
@@ -50,11 +50,11 @@ int foo() {
 // UDL function, and that the constexpr f1 and f2 functions both return a
 // constant value.
 
-// CHECK-NOT: define{{.*}} zeroext i8 @_ZN10Issue54578li3_UCEy
+// CHECK-NOT: define{{.*}} i8 @_ZN10Issue54578li3_UCEy
 // CHECK: define{{.*}} i32 @_ZN10Issue545783fooEv(
-// CHECK: define{{.*}} signext i8 @_ZN10Issue545782f1IcEEcT_(
+// CHECK: define{{.*}} i8 @_ZN10Issue545782f1IcEEcT_(
 // CHECK: ret i8 4
-// CHECK: define{{.*}} signext i8 @_ZN10Issue545782f2IcEEcT_(
+// CHECK: define{{.*}} i8 @_ZN10Issue545782f2IcEEcT_(
 // CHECK: ret i8 4
 }
 
diff --git a/clang/test/CodeGenCXX/ext-int.cpp 
b/clang/test/CodeGenCXX/ext-int.cpp
index a45720c53e8772..6ea5d2e7dcd8eb 100644
--- a/clang/test/CodeGenCXX/ext-int.cpp
+++ b/clang/test/CodeGenCXX/ext-int.cpp
@@ -150,9 +150,9 @@ void ManglingInstantiator() {
   // LIN: call void @_Z16ManglingTestNTTPILDB99_993EEvv()
   // WIN: call void @"??$ManglingTestNTTP@$0DOB@@@YAXXZ"()
   ManglingDependent<4>();
-  // LIN: call signext i4 @_Z17ManglingDependentILi4EEDTtlDBT__EEv()
+  // LIN: call i4 @_Z17ManglingDependentILi4EEDTtlDBT__EEv()
   // WIN64: call i4 @"??$ManglingDependent@$03@@YAU?$_BitInt@$03@__clang@@XZ"()
-  // WIN32: call signext i4 
@"??$ManglingDependent@$03@@YAU?$_BitInt@$03@__clang@@XZ"()
+  // WIN32: call i4 @"??$ManglingDependent@$03@@YAU?$_BitInt@$03@__clang@@XZ"()
   uint16_t4 V;
   ManglingTestTemplateParam(V);
   // LIN: call void @_Z25ManglingTestTemplateParamIDv4_DU16_EvRT_(ptr
diff --git a/clang/test/CodeGenCXX/ms-inline-asm-return.cpp 
b/clang/test/CodeGenCXX/ms-inline-asm-return.cpp
index 30167b000abe71..afcd32a4659cad 100644
--- a/clang/test/CodeGenCXX/ms-inline-asm-return.cpp
+++ b/clang/test/CodeGenCXX/ms-inline-asm-return.cpp
@@ -61,7 +61,7 @@ short f_i16() {
     mov edx, 1
   }
 }
-// CHECK-LABEL: define dso_local signext i16 @f_i16()
+// CHECK-LABEL: define dso_local i16 @f_i16()
 // CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, 
$$1\0A\09mov edx, $$1", "=&{eax},~{edx},{{.*}}"
 // CHECK: %[[r_i16:[^ ]*]] = trunc i32 %[[r]] to i16
 // CHECK: ret i16 %[[r_i16]]
@@ -72,7 +72,7 @@ char f_i8() {
     mov edx, 1
   }
 }
-// CHECK-LABEL: define dso_local signext i8 @f_i8()
+// CHECK-LABEL: define dso_local i8 @f_i8()
 // CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, 
$$1\0A\09mov edx, $$1", "=&{eax},~{edx},{{.*}}"
 // CHECK: %[[r_i8:[^ ]*]] = trunc i32 %[[r]] to i8
 // CHECK: ret i8 %[[r_i8]]
diff --git a/clang/test/CodeGenCXX/pr12251.cpp 
b/clang/test/CodeGenCXX/pr12251.cpp
index bd5c85b83f2caf..b9c66f7c0094bb 100644
--- a/clang/test/CodeGenCXX/pr12251.cpp
+++ b/clang/test/CodeGenCXX/pr12251.cpp
@@ -103,7 +103,7 @@ enum e13 : char {e13_a = -1 };
 e13 g13(e13 *x) {
   return *x;
 }
-// CHECK-LABEL: define{{.*}} signext i8 @_Z3g13P3e13
+// CHECK-LABEL: define{{.*}} i8 @_Z3g13P3e13
 // CHECK: load i8, ptr %x, align 1
 // CHECK-NOT: range
 // CHECK: ret
diff --git a/clang/test/CodeGenObjC/property.m 
b/clang/test/CodeGenObjC/property.m
index 0c604bfc13532e..057470d9422dfc 100644
--- a/clang/test/CodeGenObjC/property.m
+++ b/clang/test/CodeGenObjC/property.m
@@ -131,7 +131,7 @@ void test7(Test7 *t) {
 // CHECK-NEXT: store
 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[T]], align
 // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES
-// CHECK-NEXT: [[T2:%.*]] = call zeroext i8
+// CHECK-NEXT: [[T2:%.*]] = call i8
 // CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
 // CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 2
 // CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
@@ -139,7 +139,7 @@ void test7(Test7 *t) {
 // CHECK-NEXT: call void
 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[T]], align
 // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES
-// CHECK-NEXT: [[T2:%.*]] = call zeroext i8
+// CHECK-NEXT: [[T2:%.*]] = call i8
 // CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
 // CHECK-NEXT: [[T4:%.*]] = or i32 [[T3]], 5
 // CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
@@ -147,7 +147,7 @@ void test7(Test7 *t) {
 // CHECK-NEXT: call void
 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[T]], align
 // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES
-// CHECK-NEXT: [[T2:%.*]] = call zeroext i8
+// CHECK-NEXT: [[T2:%.*]] = call i8
 // CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
 // CHECK-NEXT: [[T4:%.*]] = xor i32 [[T3]], 8
 // CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
diff --git a/clang/test/DebugInfo/CXX/ptr-to-ptr.cpp 
b/clang/test/DebugInfo/CXX/ptr-to-ptr.cpp
index 12e50a59fab4dc..45f2aa5ee56c36 100644
--- a/clang/test/DebugInfo/CXX/ptr-to-ptr.cpp
+++ b/clang/test/DebugInfo/CXX/ptr-to-ptr.cpp
@@ -51,7 +51,7 @@ int func3(B *b) {
   return local1->i;
 }
 
-// CHECK-LABEL: define dso_local noundef signext i8 @{{.*}}func4{{.*}}(
+// CHECK-LABEL: define dso_local noundef i8 @{{.*}}func4{{.*}}(
 // CHECK:         [[A_ADDR:%.*]] = getelementptr inbounds nuw %class.C, ptr 
{{%.*}}, i32 0, i32 1
 // CHECK-NEXT:    [[A:%.*]] = load ptr, ptr [[A_ADDR]],
 // CHECK-NEXT:      #dbg_value(ptr [[A]], [[META6:![0-9]+]], !DIExpression(),
@@ -64,7 +64,7 @@ char func4(C *c) {
   return foo(c->a->i)->c;
 }
 
-// CHECK-LABEL: define dso_local noundef signext i8 @{{.*}}func5{{.*}}(
+// CHECK-LABEL: define dso_local noundef i8 @{{.*}}func5{{.*}}(
 // CHECK:           #dbg_declare(ptr {{%.*}}, [[META7:![0-9]+]], 
!DIExpression(),
 // CHECK:           #dbg_declare(ptr {{%.*}}, [[META8:![0-9]+]], 
!DIExpression(),
 // CHECK:         [[A_ADDR:%.*]] = getelementptr inbounds %class.A, ptr 
{{%.*}}, i64 {{%.*}},
diff --git a/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp 
b/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp
index 724fb3ea96bb5c..934cd91c31614f 100644
--- a/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp
@@ -2510,7 +2510,7 @@ int main() {
 // CHECK1-NEXT:    [[KERNEL_ARGS5:%.*]] = alloca 
[[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8
 // CHECK1-NEXT:    store i32 0, ptr [[RETVAL]], align 4
 // CHECK1-NEXT:    call void @_ZN1SC1El(ptr noundef nonnull align 8 
dereferenceable(24) [[S]], i64 noundef 0)
-// CHECK1-NEXT:    [[CALL:%.*]] = invoke noundef signext i8 @_ZN1ScvcEv(ptr 
noundef nonnull align 8 dereferenceable(24) [[S]])
+// CHECK1-NEXT:    [[CALL:%.*]] = invoke noundef i8 @_ZN1ScvcEv(ptr noundef 
nonnull align 8 dereferenceable(24) [[S]])
 // CHECK1-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label 
[[LPAD:%.*]]
 // CHECK1:       invoke.cont:
 // CHECK1-NEXT:    store i8 [[CALL]], ptr [[A]], align 1
@@ -3704,7 +3704,7 @@ int main() {
 // CHECK1-NEXT:    invoke void @_ZN1SC1El(ptr noundef nonnull align 8 
dereferenceable(24) [[REF_TMP]], i64 noundef 23)
 // CHECK1-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label 
[[TERMINATE_LPAD:%.*]]
 // CHECK1:       invoke.cont:
-// CHECK1-NEXT:    [[CALL:%.*]] = invoke noundef signext i8 @_ZN1ScvcEv(ptr 
noundef nonnull align 8 dereferenceable(24) [[REF_TMP]])
+// CHECK1-NEXT:    [[CALL:%.*]] = invoke noundef i8 @_ZN1ScvcEv(ptr noundef 
nonnull align 8 dereferenceable(24) [[REF_TMP]])
 // CHECK1-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label 
[[TERMINATE_LPAD]]
 // CHECK1:       invoke.cont2:
 // CHECK1-NEXT:    [[TMP7:%.*]] = sext i8 [[CALL]] to i32
@@ -3835,7 +3835,7 @@ int main() {
 // CHECK5-NEXT:    [[KERNEL_ARGS5:%.*]] = alloca 
[[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8
 // CHECK5-NEXT:    store i32 0, ptr [[RETVAL]], align 4
 // CHECK5-NEXT:    call void @_ZN1SC1El(ptr noundef nonnull align 8 
dereferenceable(24) [[S]], i64 noundef 0)
-// CHECK5-NEXT:    [[CALL:%.*]] = invoke noundef signext i8 @_ZN1ScvcEv(ptr 
noundef nonnull align 8 dereferenceable(24) [[S]])
+// CHECK5-NEXT:    [[CALL:%.*]] = invoke noundef i8 @_ZN1ScvcEv(ptr noundef 
nonnull align 8 dereferenceable(24) [[S]])
 // CHECK5-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label 
[[LPAD:%.*]]
 // CHECK5:       invoke.cont:
 // CHECK5-NEXT:    store i8 [[CALL]], ptr [[A]], align 1
@@ -5020,7 +5020,7 @@ int main() {
 // CHECK5-NEXT:    invoke void @_ZN1SC1El(ptr noundef nonnull align 8 
dereferenceable(24) [[REF_TMP]], i64 noundef 23)
 // CHECK5-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label 
[[TERMINATE_LPAD:%.*]]
 // CHECK5:       invoke.cont:
-// CHECK5-NEXT:    [[CALL:%.*]] = invoke noundef signext i8 @_ZN1ScvcEv(ptr 
noundef nonnull align 8 dereferenceable(24) [[REF_TMP]])
+// CHECK5-NEXT:    [[CALL:%.*]] = invoke noundef i8 @_ZN1ScvcEv(ptr noundef 
nonnull align 8 dereferenceable(24) [[REF_TMP]])
 // CHECK5-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label 
[[TERMINATE_LPAD]]
 // CHECK5:       invoke.cont2:
 // CHECK5-NEXT:    [[TMP7:%.*]] = sext i8 [[CALL]] to i32
diff --git 
a/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp 
b/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp
index 9359b39dd48414..db4123c75dbc70 100644
--- a/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp
@@ -114,7 +114,7 @@ int main() {
 // CHECK1-NEXT:    [[KERNEL_ARGS5:%.*]] = alloca 
[[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8
 // CHECK1-NEXT:    store i32 0, ptr [[RETVAL]], align 4
 // CHECK1-NEXT:    call void @_ZN1SC1El(ptr nonnull align 8 
dereferenceable(24) [[S]], i64 0)
-// CHECK1-NEXT:    [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(ptr nonnull 
align 8 dereferenceable(24) [[S]])
+// CHECK1-NEXT:    [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(ptr nonnull align 8 
dereferenceable(24) [[S]])
 // CHECK1-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label 
[[LPAD:%.*]]
 // CHECK1:       invoke.cont:
 // CHECK1-NEXT:    store i8 [[CALL]], ptr [[A]], align 1
@@ -1378,7 +1378,7 @@ int main() {
 // CHECK1-NEXT:    invoke void @_ZN1SC1El(ptr nonnull align 8 
dereferenceable(24) [[REF_TMP]], i64 23)
 // CHECK1-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label 
[[TERMINATE_LPAD:%.*]], !llvm.access.group [[ACC_GRP48]]
 // CHECK1:       invoke.cont:
-// CHECK1-NEXT:    [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(ptr nonnull 
align 8 dereferenceable(24) [[REF_TMP]])
+// CHECK1-NEXT:    [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(ptr nonnull align 8 
dereferenceable(24) [[REF_TMP]])
 // CHECK1-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label 
[[TERMINATE_LPAD]], !llvm.access.group [[ACC_GRP48]]
 // CHECK1:       invoke.cont2:
 // CHECK1-NEXT:    [[TMP7:%.*]] = sext i8 [[CALL]] to i32
@@ -1522,7 +1522,7 @@ int main() {
 // CHECK3-NEXT:    [[I7:%.*]] = alloca i32, align 4
 // CHECK3-NEXT:    store i32 0, ptr [[RETVAL]], align 4
 // CHECK3-NEXT:    call void @_ZN1SC1El(ptr nonnull align 8 
dereferenceable(24) [[S]], i64 0)
-// CHECK3-NEXT:    [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(ptr nonnull 
align 8 dereferenceable(24) [[S]])
+// CHECK3-NEXT:    [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(ptr nonnull align 8 
dereferenceable(24) [[S]])
 // CHECK3-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label 
[[LPAD:%.*]]
 // CHECK3:       invoke.cont:
 // CHECK3-NEXT:    store i8 [[CALL]], ptr [[A]], align 1
@@ -1862,7 +1862,7 @@ int main() {
 // CHECK5-NEXT:    [[KERNEL_ARGS5:%.*]] = alloca 
[[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8
 // CHECK5-NEXT:    store i32 0, ptr [[RETVAL]], align 4
 // CHECK5-NEXT:    call void @_ZN1SC1El(ptr nonnull align 8 
dereferenceable(24) [[S]], i64 0)
-// CHECK5-NEXT:    [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(ptr nonnull 
align 8 dereferenceable(24) [[S]])
+// CHECK5-NEXT:    [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(ptr nonnull align 8 
dereferenceable(24) [[S]])
 // CHECK5-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label 
[[LPAD:%.*]]
 // CHECK5:       invoke.cont:
 // CHECK5-NEXT:    store i8 [[CALL]], ptr [[A]], align 1
@@ -3117,7 +3117,7 @@ int main() {
 // CHECK5-NEXT:    invoke void @_ZN1SC1El(ptr nonnull align 8 
dereferenceable(24) [[REF_TMP]], i64 23)
 // CHECK5-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label 
[[TERMINATE_LPAD:%.*]], !llvm.access.group [[ACC_GRP48]]
 // CHECK5:       invoke.cont:
-// CHECK5-NEXT:    [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(ptr nonnull 
align 8 dereferenceable(24) [[REF_TMP]])
+// CHECK5-NEXT:    [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(ptr nonnull align 8 
dereferenceable(24) [[REF_TMP]])
 // CHECK5-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label 
[[TERMINATE_LPAD]], !llvm.access.group [[ACC_GRP48]]
 // CHECK5:       invoke.cont2:
 // CHECK5-NEXT:    [[TMP7:%.*]] = sext i8 [[CALL]] to i32
diff --git a/llvm/lib/ABI/Targets/X86.cpp b/llvm/lib/ABI/Targets/X86.cpp
index d57c5a0cf516f4..26f2d682ad5d31 100644
--- a/llvm/lib/ABI/Targets/X86.cpp
+++ b/llvm/lib/ABI/Targets/X86.cpp
@@ -75,6 +75,8 @@ class X86_64TargetInfo : public TargetInfo {
                                unsigned &NeededInt, unsigned &NeededSse,
                                bool IsNamedArg, bool IsRegCall = false) const;
 
+  bool shouldExtendReturnType(const IntegerType *RetTy) const;
+
 public:
   X86_64TargetInfo(TypeBuilder &TypeBuilder, X86AVXABILevel AVXABILevel,
                    bool Has64BitPtrs, const X86ABICompatInfo &Compat)
@@ -138,6 +140,19 @@ static const Type *reduceUnionForX8664(const RecordType 
*UnionType,
   return StorageType;
 }
 
+bool X86_64TargetInfo::shouldExtendReturnType(const IntegerType *RetTy) const {
+  // Bools need to be zero-extended to 8 bits for all ABIs.
+  if (RetTy->isBool())
+    return true;
+
+  // Promotable integer types get extended only for Darwin.
+  bool IsDarwin = false; // TODO: Currently not supported by ABI library.
+  if (!IsDarwin)
+    return false;
+
+  return isPromotableInteger(RetTy);
+}
+
 void X86_64TargetInfo::postMerge(unsigned AggregateSize, Class &Lo,
                                  Class &Hi) const {
   // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
@@ -743,10 +758,10 @@ ArgInfo X86_64TargetInfo::classifyReturnType(const Type 
*RetTy) const {
     // If we have a sign or zero extended integer, make sure to return Extend
     // so that the parameter gets the right LLVM IR attributes.
     if (Hi == NoClass && ResType->isInteger()) {
-      if (const IntegerType *IntTy = dyn_cast<IntegerType>(RetTy)) {
+      if (const IntegerType *IntTy = dyn_cast<IntegerType>(RetTy))
         if (isPromotableInteger(IntTy))
-          return ArgInfo::getExtend(RetTy);
-      }
+          return shouldExtendReturnType(IntTy) ? ArgInfo::getExtend(RetTy)
+                                               : ArgInfo::getDirect(RetTy);
     }
     if (ResType->isInteger() && ResType->getSizeInBits() == 128) {
       assert(Hi == Integer);
@@ -1315,7 +1330,7 @@ ArgInfo X86_64TargetInfo::getIndirectReturnResult(const 
Type *Ty) const {
     if (const auto *IntTy = dyn_cast<IntegerType>(Ty)) {
       if (IntTy->isBitInt())
         return getNaturalAlignIndirect(IntTy, getAllocaAddrSpace());
-      if (isPromotableInteger(IntTy))
+      if (shouldExtendReturnType(IntTy))
         return ArgInfo::getExtend(Ty);
     }
     return ArgInfo::getDirect();
diff --git a/llvm/unittests/ABI/X86TargetInfoTest.cpp 
b/llvm/unittests/ABI/X86TargetInfoTest.cpp
index 2d971f74c2ee3b..29dfb4ce1de362 100644
--- a/llvm/unittests/ABI/X86TargetInfoTest.cpp
+++ b/llvm/unittests/ABI/X86TargetInfoTest.cpp
@@ -39,6 +39,7 @@ class X86TargetInfoTest : public ::testing::Test {
   llvm::BumpPtrAllocator Alloc;
   TypeBuilder TB;
   const ABIType *I8;
+  const ABIType *I16;
   const ABIType *I32;
   const ABIType *I64;
   const ABIType *F32;
@@ -56,6 +57,7 @@ class X86TargetInfoTest : public ::testing::Test {
 
   X86TargetInfoTest()
       : TB(Alloc), I8(TB.getIntegerType(8, llvm::Align(1), /*Signed=*/true)),
+        I16(TB.getIntegerType(16, llvm::Align(2), /*Signed=*/true)),
         I32(TB.getIntegerType(32, llvm::Align(4), /*Signed=*/true)),
         I64(TB.getIntegerType(64, llvm::Align(8), /*Signed=*/true)),
         F32(TB.getFloatType(llvm::APFloat::IEEEsingle(), llvm::Align(4))),
@@ -112,6 +114,16 @@ class X86TargetInfoTest : public ::testing::Test {
     TI->computeInfo(*FI);
     return FI->getArgInfo(0).Info;
   }
+
+  const ArgInfo &classifyRet(const ABIType *RetTy,
+                             std::unique_ptr<FunctionInfo> &FI,
+                             std::unique_ptr<TargetInfo> &TI,
+                             X86AVXABILevel AVXLevel = X86AVXABILevel::None) {
+    TI = target(AVXLevel);
+    FI = FunctionInfo::create(llvm::CallingConv::C, RetTy, {});
+    TI->computeInfo(*FI);
+    return FI->getReturnInfo();
+  }
 };
 
 static void expectDirectInteger(const ArgInfo &Info, unsigned Bits) {
@@ -123,6 +135,13 @@ static void expectDirectInteger(const ArgInfo &Info, 
unsigned Bits) {
   EXPECT_EQ(IT->getSizeInBits().getFixedValue(), Bits);
 }
 
+static void expectExtendInteger(const ArgInfo &Info, const ABIType *Ty,
+                                bool IsSigned) {
+  EXPECT_TRUE(Info.isExtend());
+  EXPECT_EQ(Info.isSignExt(), IsSigned);
+  EXPECT_EQ(Info.getCoerceToType(), Ty);
+}
+
 static void expectInteger(const ABIType *Ty, unsigned Bits) {
   const auto *IT = llvm::dyn_cast<llvm::abi::IntegerType>(Ty);
   ASSERT_NE(IT, nullptr);
@@ -907,4 +926,34 @@ TEST_F(X86TargetInfoTest, 
BitIntVectorInMemoryIsNotNarrowed) {
   expectInteger(Pair[1].FieldType, 64);
 }
 
+TEST_F(X86TargetInfoTest, IntReturnExtension) {
+  std::unique_ptr<FunctionInfo> FI;
+  std::unique_ptr<TargetInfo> TI;
+
+  // bool must be zero-extended.
+  expectExtendInteger(classifyRet(Bool, FI, TI), Bool, /*IsSigned=*/false);
+
+  // _BitInt(1) types must not be extended.
+  const ABIType *BitInt1 =
+      TB.getIntegerType(1, llvm::Align(1), /*IsSigned=*/false,
+                        /*IsBitInt=*/true);
+  expectDirectInteger(classifyRet(BitInt1, FI, TI), 1);
+  const ABIType *BitInt13 =
+      TB.getIntegerType(13, llvm::Align(2), /*IsSigned=*/true,
+                        /*IsBitInt=*/true);
+  expectDirectInteger(classifyRet(BitInt13, FI, TI), 13);
+
+  // _BitInt > 32-bit gets passed as 64-bit, to match Clang ABI behavior.
+  // Returning this as i40 would be equivalent.
+  const ABIType *BitInt40 =
+      TB.getIntegerType(40, llvm::Align(8), /*IsSigned=*/false,
+                        /*IsBitInt=*/true);
+  expectDirectInteger(classifyRet(BitInt40, FI, TI), 64);
+
+  // char, short and int must not be extended.
+  expectDirectInteger(classifyRet(I8, FI, TI), 8);
+  expectDirectInteger(classifyRet(I16, FI, TI), 16);
+  expectDirectInteger(classifyRet(I32, FI, TI), 32);
+}
+
 } // namespace

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to