[clang] [llvm] [Clang][ABI][X86] Do not emit zeroext/signext for return values (PR #232729)
Nikita Popov via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 16 05:57:57 PDT 2026
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 <npopov at redhat.com>
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 at __clang@@XZ"()
- // WIN32: call signext i4 @"??$ManglingDependent@$03@@YAU?$_BitInt@$03 at __clang@@XZ"()
+ // WIN32: call i4 @"??$ManglingDependent@$03@@YAU?$_BitInt@$03 at __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
More information about the cfe-commits
mailing list