- Notifications
You must be signed in to change notification settings - Fork 15.3k
[Inliner] Fix bug when propagating poison generating return attributes #66036
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| @llvm/pr-subscribers-backend-x86 Changes
-- Patch is 373.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66036.diff 45 Files Affected:
diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c index 44f8cbe2cc01739..642b08ac68ef122 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c @@ -636,31 +636,31 @@ void test_core(void) { // CHECK-ASM: vlbb vsc = vec_load_len(cptrsc, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vuc = vec_load_len(cptruc, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vss = vec_load_len(cptrss, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vus = vec_load_len(cptrus, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vsi = vec_load_len(cptrsi, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vui = vec_load_len(cptrui, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vsl = vec_load_len(cptrsl, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vul = vec_load_len(cptrul, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vd = vec_load_len(cptrd, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vec_store_len(vsc, ptrsc, idx); diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c index 416ca0ddd1b4fe2..3f02565dfb488ce 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c @@ -207,10 +207,10 @@ void test_core(void) { // CHECK-ASM: vlbb vf = vec_load_len(cptrf, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vd = vec_load_len(cptrd, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vec_store_len(vf, ptrf, idx); @@ -221,10 +221,10 @@ void test_core(void) { // CHECK-ASM: vstl vuc = vec_load_len_r(cptruc, 0); - // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 0, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 0, ptr readonly %{{.*}}) // CHECK-ASM: vlrl %{{.*}}, 0(%{{.*}}), 0 vuc = vec_load_len_r(cptruc, idx); - // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vlrlr vec_store_len_r(vuc, ptruc, 0); diff --git a/clang/test/CodeGen/X86/bitscan-builtins.c b/clang/test/CodeGen/X86/bitscan-builtins.c index a5a7808a82a234d..d75f7c1ab2f1ed4 100644 --- a/clang/test/CodeGen/X86/bitscan-builtins.c +++ b/clang/test/CodeGen/X86/bitscan-builtins.c @@ -1,9 +1,6 @@ // RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s - // PR33722 // RUN: %clang_cc1 -x c -ffreestanding %s -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - | FileCheck %s #include diff --git a/clang/test/CodeGen/X86/bitscan-builtins.cpp b/clang/test/CodeGen/X86/bitscan-builtins.cpp new file mode 100644 index 000000000000000..ab8a0fa2f24773b --- /dev/null +++ b/clang/test/CodeGen/X86/bitscan-builtins.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s + +// PR33722 +// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - | FileCheck %s + +#include + +int test_bit_scan_forward(int a) { +// CHECK-LABEL: test_bit_scan_forward +// CHECK: %[[call:.*]] = call noundef i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true) +// CHECK: ret i32 %[[call]] + return _bit_scan_forward(a); +} + +int test_bit_scan_reverse(int a) { +// CHECK-LABEL: test_bit_scan_reverse +// CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true) +// CHECK: %[[sub:.*]] = sub nsw i32 31, %[[call]] +// CHECK: ret i32 %[[sub]] + return _bit_scan_reverse(a); +} + +int test__bsfd(int X) { +// CHECK-LABEL: test__bsfd +// CHECK: %[[call:.*]] = call noundef i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true) + return __bsfd(X); +} + +int test__bsfq(long long X) { +// CHECK-LABEL: test__bsfq +// CHECK: %[[call:.*]] = call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 true) + return __bsfq(X); +} + +int test__bsrd(int X) { +// CHECK-LABEL: test__bsrd +// CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true) +// CHECK: %[[sub:.*]] = sub nsw i32 31, %[[call]] + return __bsrd(X); +} + +int test__bsrq(long long X) { +// CHECK-LABEL: test__bsrq +// CHECK: %[[call:.*]] = call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 true) +// CHECK: %[[cast:.*]] = trunc i64 %[[call]] to i32 +// CHECK: %[[sub:.*]] = sub nsw i32 63, %[[cast]] + return __bsrq(X); +} + +// Test constexpr handling. +#if defined(__cplusplus) && (__cplusplus >= 201103L) + +char bsf_0[_bit_scan_forward(0x00000001) == 0 ? 1 : -1]; +char bsf_1[_bit_scan_forward(0x10000000) == 28 ? 1 : -1]; + +char bsr_0[_bit_scan_reverse(0x00000001) == 0 ? 1 : -1]; +char bsr_1[_bit_scan_reverse(0x01000000) == 24 ? 1 : -1]; + +char bsfd_0[__bsfd(0x00000008) == 3 ? 1 : -1]; +char bsfd_1[__bsfd(0x00010008) == 3 ? 1 : -1]; + +char bsrd_0[__bsrd(0x00000010) == 4 ? 1 : -1]; +char bsrd_1[__bsrd(0x00100100) == 20 ? 1 : -1]; + +char bsfq_0[__bsfq(0x0000000800000000ULL) == 35 ? 1 : -1]; +char bsfq_1[__bsfq(0x0004000000000000ULL) == 50 ? 1 : -1]; + +char bsrq_0[__bsrq(0x0000100800000000ULL) == 44 ? 1 : -1]; +char bsrq_1[__bsrq(0x0004000100000000ULL) == 50 ? 1 : -1]; + +#endif diff --git a/clang/test/CodeGen/X86/popcnt-builtins.c b/clang/test/CodeGen/X86/popcnt-builtins.c index e59ffaa031a6a10..b9bc666a1e28ad2 100644 --- a/clang/test/CodeGen/X86/popcnt-builtins.c +++ b/clang/test/CodeGen/X86/popcnt-builtins.c @@ -1,7 +1,5 @@ // RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT // RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s #include diff --git a/clang/test/CodeGen/X86/popcnt-builtins.cpp b/clang/test/CodeGen/X86/popcnt-builtins.cpp new file mode 100644 index 000000000000000..42996c547e0af9b --- /dev/null +++ b/clang/test/CodeGen/X86/popcnt-builtins.cpp @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s + +#include + +#ifdef __POPCNT__ +int test_mm_popcnt_u32(unsigned int __X) { + //CHECK-POPCNT: call noundef i32 @llvm.ctpop.i32 + return _mm_popcnt_u32(__X); +} +#endif + +int test_popcnt32(unsigned int __X) { + //CHECK: call noundef i32 @llvm.ctpop.i32 + return _popcnt32(__X); +} + +int test__popcntd(unsigned int __X) { + //CHECK: call noundef i32 @llvm.ctpop.i32 + return __popcntd(__X); +} + +#ifdef __x86_64__ +#ifdef __POPCNT__ +long long test_mm_popcnt_u64(unsigned long long __X) { + //CHECK-POPCNT: call i64 @llvm.ctpop.i64 + return _mm_popcnt_u64(__X); +} +#endif + +long long test_popcnt64(unsigned long long __X) { + //CHECK: call i64 @llvm.ctpop.i64 + return _popcnt64(__X); +} + +long long test__popcntq(unsigned long long __X) { + //CHECK: call i64 @llvm.ctpop.i64 + return __popcntq(__X); +} +#endif + +// Test constexpr handling. +#if defined(__cplusplus) && (__cplusplus >= 201103L) +#if defined(__POPCNT__) +char ctpop32_0[_mm_popcnt_u32(0x00000000) == 0 ? 1 : -1]; +char ctpop32_1[_mm_popcnt_u32(0x000000F0) == 4 ? 1 : -1]; +#endif + +char popcnt32_0[_popcnt32(0x00000000) == 0 ? 1 : -1]; +char popcnt32_1[_popcnt32(0x100000F0) == 5 ? 1 : -1]; + +char popcntd_0[__popcntd(0x00000000) == 0 ? 1 : -1]; +char popcntd_1[__popcntd(0x00F000F0) == 8 ? 1 : -1]; + +#ifdef __x86_64__ +#if defined(__POPCNT__) +char ctpop64_0[_mm_popcnt_u64(0x0000000000000000ULL) == 0 ? 1 : -1]; +char ctpop64_1[_mm_popcnt_u64(0xF000000000000001ULL) == 5 ? 1 : -1]; +#endif + +char popcnt64_0[_popcnt64(0x0000000000000000ULL) == 0 ? 1 : -1]; +char popcnt64_1[_popcnt64(0xF00000F000000001ULL) == 9 ? 1 : -1]; + +char popcntq_0[__popcntq(0x0000000000000000ULL) == 0 ? 1 : -1]; +char popcntq_1[__popcntq(0xF000010000300001ULL) == 8 ? 1 : -1]; +#endif +#endif diff --git a/clang/test/CodeGen/X86/rot-intrinsics.c b/clang/test/CodeGen/X86/rot-intrinsics.c index f8c78119a1c4a77..70bda329ce860c9 100644 --- a/clang/test/CodeGen/X86/rot-intrinsics.c +++ b/clang/test/CodeGen/X86/rot-intrinsics.c @@ -5,13 +5,6 @@ // RUN: %clang_cc1 -x c -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG // RUN: %clang_cc1 -x c -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple i686--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple x86_64--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG - #include unsigned char test__rolb(unsigned char value, int shift) { diff --git a/clang/test/CodeGen/X86/rot-intrinsics.cpp b/clang/test/CodeGen/X86/rot-intrinsics.cpp new file mode 100644 index 000000000000000..90afa91f335e83d --- /dev/null +++ b/clang/test/CodeGen/X86/rot-intrinsics.cpp @@ -0,0 +1,165 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple i686--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-NO-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple x86_64--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-NO-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-NO-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-COMPAT17 + +#include + +unsigned char test__rolb(unsigned char value, int shift) { +// CHECK-LABEL: test__rolb +// CHECK: [[R:%.*]] = call noundef i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]]) +// CHECK: ret i8 [[R]] + return __rolb(value, shift); +} + +unsigned short test__rolw(unsigned short value, int shift) { +// CHECK-LABEL: test__rolw +// CHECK: [[R:%.*]] = call noundef i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]]) +// CHECK: ret i16 [[R]] + return __rolw(value, shift); +} + +unsigned int test__rold(unsigned int value, int shift) { +// CHECK-LABEL: test__rold +// CHECK: [[R:%.*]] = call noundef i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK: ret i32 [[R]] + return __rold(value, shift); +} + +#if defined(__x86_64__) +unsigned long test__rolq(unsigned long value, int shift) { +// CHECK-LONG-LABEL: test__rolq +// CHECK-LONG: [[R:%.*]] = call i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]]) +// CHECK-LONG: ret i64 [[R]] + return __rolq(value, shift); +} +#endif + +unsigned char test__rorb(unsigned char value, int shift) { +// CHECK-LABEL: test__rorb +// CHECK: [[R:%.*]] = call noundef i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]]) +// CHECK: ret i8 [[R]] + return __rorb(value, shift); +} + +unsigned short test__rorw(unsigned short value, int shift) { +// CHECK-LABEL: test__rorw +// CHECK: [[R:%.*]] = call noundef i16 @llvm.fshr.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]]) +// CHECK: ret i16 [[R]] + return __rorw(value, shift); +} + +unsigned int test__rord(unsigned int value, int shift) { +// CHECK-LABEL: test__rord +// CHECK: [[R:%.*]] = call noundef i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK: ret i32 [[R]] + return __rord(value, shift); +} + +#if defined(__x86_64__) +unsigned long test__rorq(unsigned long value, int shift) { +// CHECK-LONG-LABEL: test__rorq +// CHECK-LONG: [[R:%.*]] = call i64 @llvm.fshr.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]]) +// CHECK-LONG: ret i64 [[R]] + return __rorq(value, shift); +} +#endif + +unsigned short test_rotwl(unsigned short value, int shift) { +// CHECK-LABEL: test_rotwl +// CHECK: [[R:%.*]] = call noundef i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]]) +// CHECK: ret i16 [[R]] + return _rotwl(value, shift); +} + +unsigned int test_rotl(unsigned int value, int shift) { +// CHECK-32BIT-LONG-COMPAT17-LABEL: test_rotl +// CHECK-32BIT-LONG-COMPAT17: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-COMPAT17: ret i32 [[R]] +// +// CHECK-32BIT-LONG-NO-COMPAT17-LABEL: test_rotl +// CHECK-32BIT-LONG-NO-COMPAT17: [[R:%.*]] = call noundef i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-NO-COMPAT17: ret i32 [[R]] + return _rotl(value, shift); +} + +unsigned long test_lrotl(unsigned long value, int shift) { +// CHECK-32BIT-LONG-COMPAT17-LABEL: test_lrotl +// CHECK-32BIT-LONG-COMPAT17: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-COMPAT17: ret i32 [[R]] +// +// CHECK-32BIT-LONG-NO-COMPAT17-LABEL: test_lrotl +// CHECK-32BIT-LONG-NO-COMPAT17: [[R:%.*]] = call noundef i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-NO-COMPAT17: ret i32 [[R]] +// +// CHECK-64BIT-LONG-LABEL: test_lrotl +// CHECK-64BIT-LONG: [[R:%.*]] = call noundef i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]]) +// CHECK-64BIT-LONG: ret i64 [[R]] + return _lrotl(value, shift); +} + + +unsigned short test_ro... |
| @llvm/pr-subscribers-llvm-transforms Changes
-- Patch is 373.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66036.diff 45 Files Affected:
diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c index 44f8cbe2cc01739..642b08ac68ef122 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c @@ -636,31 +636,31 @@ void test_core(void) { // CHECK-ASM: vlbb vsc = vec_load_len(cptrsc, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vuc = vec_load_len(cptruc, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vss = vec_load_len(cptrss, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vus = vec_load_len(cptrus, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vsi = vec_load_len(cptrsi, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vui = vec_load_len(cptrui, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vsl = vec_load_len(cptrsl, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vul = vec_load_len(cptrul, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vd = vec_load_len(cptrd, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vec_store_len(vsc, ptrsc, idx); diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c index 416ca0ddd1b4fe2..3f02565dfb488ce 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c @@ -207,10 +207,10 @@ void test_core(void) { // CHECK-ASM: vlbb vf = vec_load_len(cptrf, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vd = vec_load_len(cptrd, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vec_store_len(vf, ptrf, idx); @@ -221,10 +221,10 @@ void test_core(void) { // CHECK-ASM: vstl vuc = vec_load_len_r(cptruc, 0); - // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 0, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 0, ptr readonly %{{.*}}) // CHECK-ASM: vlrl %{{.*}}, 0(%{{.*}}), 0 vuc = vec_load_len_r(cptruc, idx); - // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vlrlr vec_store_len_r(vuc, ptruc, 0); diff --git a/clang/test/CodeGen/X86/bitscan-builtins.c b/clang/test/CodeGen/X86/bitscan-builtins.c index a5a7808a82a234d..d75f7c1ab2f1ed4 100644 --- a/clang/test/CodeGen/X86/bitscan-builtins.c +++ b/clang/test/CodeGen/X86/bitscan-builtins.c @@ -1,9 +1,6 @@ // RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s - // PR33722 // RUN: %clang_cc1 -x c -ffreestanding %s -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - | FileCheck %s #include diff --git a/clang/test/CodeGen/X86/bitscan-builtins.cpp b/clang/test/CodeGen/X86/bitscan-builtins.cpp new file mode 100644 index 000000000000000..ab8a0fa2f24773b --- /dev/null +++ b/clang/test/CodeGen/X86/bitscan-builtins.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s + +// PR33722 +// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - | FileCheck %s + +#include + +int test_bit_scan_forward(int a) { +// CHECK-LABEL: test_bit_scan_forward +// CHECK: %[[call:.*]] = call noundef i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true) +// CHECK: ret i32 %[[call]] + return _bit_scan_forward(a); +} + +int test_bit_scan_reverse(int a) { +// CHECK-LABEL: test_bit_scan_reverse +// CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true) +// CHECK: %[[sub:.*]] = sub nsw i32 31, %[[call]] +// CHECK: ret i32 %[[sub]] + return _bit_scan_reverse(a); +} + +int test__bsfd(int X) { +// CHECK-LABEL: test__bsfd +// CHECK: %[[call:.*]] = call noundef i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true) + return __bsfd(X); +} + +int test__bsfq(long long X) { +// CHECK-LABEL: test__bsfq +// CHECK: %[[call:.*]] = call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 true) + return __bsfq(X); +} + +int test__bsrd(int X) { +// CHECK-LABEL: test__bsrd +// CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true) +// CHECK: %[[sub:.*]] = sub nsw i32 31, %[[call]] + return __bsrd(X); +} + +int test__bsrq(long long X) { +// CHECK-LABEL: test__bsrq +// CHECK: %[[call:.*]] = call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 true) +// CHECK: %[[cast:.*]] = trunc i64 %[[call]] to i32 +// CHECK: %[[sub:.*]] = sub nsw i32 63, %[[cast]] + return __bsrq(X); +} + +// Test constexpr handling. +#if defined(__cplusplus) && (__cplusplus >= 201103L) + +char bsf_0[_bit_scan_forward(0x00000001) == 0 ? 1 : -1]; +char bsf_1[_bit_scan_forward(0x10000000) == 28 ? 1 : -1]; + +char bsr_0[_bit_scan_reverse(0x00000001) == 0 ? 1 : -1]; +char bsr_1[_bit_scan_reverse(0x01000000) == 24 ? 1 : -1]; + +char bsfd_0[__bsfd(0x00000008) == 3 ? 1 : -1]; +char bsfd_1[__bsfd(0x00010008) == 3 ? 1 : -1]; + +char bsrd_0[__bsrd(0x00000010) == 4 ? 1 : -1]; +char bsrd_1[__bsrd(0x00100100) == 20 ? 1 : -1]; + +char bsfq_0[__bsfq(0x0000000800000000ULL) == 35 ? 1 : -1]; +char bsfq_1[__bsfq(0x0004000000000000ULL) == 50 ? 1 : -1]; + +char bsrq_0[__bsrq(0x0000100800000000ULL) == 44 ? 1 : -1]; +char bsrq_1[__bsrq(0x0004000100000000ULL) == 50 ? 1 : -1]; + +#endif diff --git a/clang/test/CodeGen/X86/popcnt-builtins.c b/clang/test/CodeGen/X86/popcnt-builtins.c index e59ffaa031a6a10..b9bc666a1e28ad2 100644 --- a/clang/test/CodeGen/X86/popcnt-builtins.c +++ b/clang/test/CodeGen/X86/popcnt-builtins.c @@ -1,7 +1,5 @@ // RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT // RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s #include diff --git a/clang/test/CodeGen/X86/popcnt-builtins.cpp b/clang/test/CodeGen/X86/popcnt-builtins.cpp new file mode 100644 index 000000000000000..42996c547e0af9b --- /dev/null +++ b/clang/test/CodeGen/X86/popcnt-builtins.cpp @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s + +#include + +#ifdef __POPCNT__ +int test_mm_popcnt_u32(unsigned int __X) { + //CHECK-POPCNT: call noundef i32 @llvm.ctpop.i32 + return _mm_popcnt_u32(__X); +} +#endif + +int test_popcnt32(unsigned int __X) { + //CHECK: call noundef i32 @llvm.ctpop.i32 + return _popcnt32(__X); +} + +int test__popcntd(unsigned int __X) { + //CHECK: call noundef i32 @llvm.ctpop.i32 + return __popcntd(__X); +} + +#ifdef __x86_64__ +#ifdef __POPCNT__ +long long test_mm_popcnt_u64(unsigned long long __X) { + //CHECK-POPCNT: call i64 @llvm.ctpop.i64 + return _mm_popcnt_u64(__X); +} +#endif + +long long test_popcnt64(unsigned long long __X) { + //CHECK: call i64 @llvm.ctpop.i64 + return _popcnt64(__X); +} + +long long test__popcntq(unsigned long long __X) { + //CHECK: call i64 @llvm.ctpop.i64 + return __popcntq(__X); +} +#endif + +// Test constexpr handling. +#if defined(__cplusplus) && (__cplusplus >= 201103L) +#if defined(__POPCNT__) +char ctpop32_0[_mm_popcnt_u32(0x00000000) == 0 ? 1 : -1]; +char ctpop32_1[_mm_popcnt_u32(0x000000F0) == 4 ? 1 : -1]; +#endif + +char popcnt32_0[_popcnt32(0x00000000) == 0 ? 1 : -1]; +char popcnt32_1[_popcnt32(0x100000F0) == 5 ? 1 : -1]; + +char popcntd_0[__popcntd(0x00000000) == 0 ? 1 : -1]; +char popcntd_1[__popcntd(0x00F000F0) == 8 ? 1 : -1]; + +#ifdef __x86_64__ +#if defined(__POPCNT__) +char ctpop64_0[_mm_popcnt_u64(0x0000000000000000ULL) == 0 ? 1 : -1]; +char ctpop64_1[_mm_popcnt_u64(0xF000000000000001ULL) == 5 ? 1 : -1]; +#endif + +char popcnt64_0[_popcnt64(0x0000000000000000ULL) == 0 ? 1 : -1]; +char popcnt64_1[_popcnt64(0xF00000F000000001ULL) == 9 ? 1 : -1]; + +char popcntq_0[__popcntq(0x0000000000000000ULL) == 0 ? 1 : -1]; +char popcntq_1[__popcntq(0xF000010000300001ULL) == 8 ? 1 : -1]; +#endif +#endif diff --git a/clang/test/CodeGen/X86/rot-intrinsics.c b/clang/test/CodeGen/X86/rot-intrinsics.c index f8c78119a1c4a77..70bda329ce860c9 100644 --- a/clang/test/CodeGen/X86/rot-intrinsics.c +++ b/clang/test/CodeGen/X86/rot-intrinsics.c @@ -5,13 +5,6 @@ // RUN: %clang_cc1 -x c -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG // RUN: %clang_cc1 -x c -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple i686--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple x86_64--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG - #include unsigned char test__rolb(unsigned char value, int shift) { diff --git a/clang/test/CodeGen/X86/rot-intrinsics.cpp b/clang/test/CodeGen/X86/rot-intrinsics.cpp new file mode 100644 index 000000000000000..90afa91f335e83d --- /dev/null +++ b/clang/test/CodeGen/X86/rot-intrinsics.cpp @@ -0,0 +1,165 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple i686--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-NO-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple x86_64--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-NO-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-NO-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-COMPAT17 + +#include + +unsigned char test__rolb(unsigned char value, int shift) { +// CHECK-LABEL: test__rolb +// CHECK: [[R:%.*]] = call noundef i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]]) +// CHECK: ret i8 [[R]] + return __rolb(value, shift); +} + +unsigned short test__rolw(unsigned short value, int shift) { +// CHECK-LABEL: test__rolw +// CHECK: [[R:%.*]] = call noundef i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]]) +// CHECK: ret i16 [[R]] + return __rolw(value, shift); +} + +unsigned int test__rold(unsigned int value, int shift) { +// CHECK-LABEL: test__rold +// CHECK: [[R:%.*]] = call noundef i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK: ret i32 [[R]] + return __rold(value, shift); +} + +#if defined(__x86_64__) +unsigned long test__rolq(unsigned long value, int shift) { +// CHECK-LONG-LABEL: test__rolq +// CHECK-LONG: [[R:%.*]] = call i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]]) +// CHECK-LONG: ret i64 [[R]] + return __rolq(value, shift); +} +#endif + +unsigned char test__rorb(unsigned char value, int shift) { +// CHECK-LABEL: test__rorb +// CHECK: [[R:%.*]] = call noundef i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]]) +// CHECK: ret i8 [[R]] + return __rorb(value, shift); +} + +unsigned short test__rorw(unsigned short value, int shift) { +// CHECK-LABEL: test__rorw +// CHECK: [[R:%.*]] = call noundef i16 @llvm.fshr.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]]) +// CHECK: ret i16 [[R]] + return __rorw(value, shift); +} + +unsigned int test__rord(unsigned int value, int shift) { +// CHECK-LABEL: test__rord +// CHECK: [[R:%.*]] = call noundef i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK: ret i32 [[R]] + return __rord(value, shift); +} + +#if defined(__x86_64__) +unsigned long test__rorq(unsigned long value, int shift) { +// CHECK-LONG-LABEL: test__rorq +// CHECK-LONG: [[R:%.*]] = call i64 @llvm.fshr.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]]) +// CHECK-LONG: ret i64 [[R]] + return __rorq(value, shift); +} +#endif + +unsigned short test_rotwl(unsigned short value, int shift) { +// CHECK-LABEL: test_rotwl +// CHECK: [[R:%.*]] = call noundef i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]]) +// CHECK: ret i16 [[R]] + return _rotwl(value, shift); +} + +unsigned int test_rotl(unsigned int value, int shift) { +// CHECK-32BIT-LONG-COMPAT17-LABEL: test_rotl +// CHECK-32BIT-LONG-COMPAT17: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-COMPAT17: ret i32 [[R]] +// +// CHECK-32BIT-LONG-NO-COMPAT17-LABEL: test_rotl +// CHECK-32BIT-LONG-NO-COMPAT17: [[R:%.*]] = call noundef i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-NO-COMPAT17: ret i32 [[R]] + return _rotl(value, shift); +} + +unsigned long test_lrotl(unsigned long value, int shift) { +// CHECK-32BIT-LONG-COMPAT17-LABEL: test_lrotl +// CHECK-32BIT-LONG-COMPAT17: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-COMPAT17: ret i32 [[R]] +// +// CHECK-32BIT-LONG-NO-COMPAT17-LABEL: test_lrotl +// CHECK-32BIT-LONG-NO-COMPAT17: [[R:%.*]] = call noundef i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-NO-COMPAT17: ret i32 [[R]] +// +// CHECK-64BIT-LONG-LABEL: test_lrotl +// CHECK-64BIT-LONG: [[R:%.*]] = call noundef i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]]) +// CHECK-64BIT-LONG: ret i64 [[R]] + return _lrotl(value, shift); +} + + +unsigned short test_ro... |
| @llvm/pr-subscribers-clang Changes
-- Patch is 373.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66036.diff 45 Files Affected:
diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c index 44f8cbe2cc01739..642b08ac68ef122 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c @@ -636,31 +636,31 @@ void test_core(void) { // CHECK-ASM: vlbb vsc = vec_load_len(cptrsc, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vuc = vec_load_len(cptruc, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vss = vec_load_len(cptrss, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vus = vec_load_len(cptrus, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vsi = vec_load_len(cptrsi, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vui = vec_load_len(cptrui, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vsl = vec_load_len(cptrsl, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vul = vec_load_len(cptrul, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vd = vec_load_len(cptrd, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vec_store_len(vsc, ptrsc, idx); diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c index 416ca0ddd1b4fe2..3f02565dfb488ce 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c @@ -207,10 +207,10 @@ void test_core(void) { // CHECK-ASM: vlbb vf = vec_load_len(cptrf, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vd = vec_load_len(cptrd, idx); - // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vll vec_store_len(vf, ptrf, idx); @@ -221,10 +221,10 @@ void test_core(void) { // CHECK-ASM: vstl vuc = vec_load_len_r(cptruc, 0); - // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 0, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 0, ptr readonly %{{.*}}) // CHECK-ASM: vlrl %{{.*}}, 0(%{{.*}}), 0 vuc = vec_load_len_r(cptruc, idx); - // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 %{{.*}}, ptr %{{.*}}) + // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 %{{.*}}, ptr readonly %{{.*}}) // CHECK-ASM: vlrlr vec_store_len_r(vuc, ptruc, 0); diff --git a/clang/test/CodeGen/X86/bitscan-builtins.c b/clang/test/CodeGen/X86/bitscan-builtins.c index a5a7808a82a234d..d75f7c1ab2f1ed4 100644 --- a/clang/test/CodeGen/X86/bitscan-builtins.c +++ b/clang/test/CodeGen/X86/bitscan-builtins.c @@ -1,9 +1,6 @@ // RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s - // PR33722 // RUN: %clang_cc1 -x c -ffreestanding %s -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - | FileCheck %s #include diff --git a/clang/test/CodeGen/X86/bitscan-builtins.cpp b/clang/test/CodeGen/X86/bitscan-builtins.cpp new file mode 100644 index 000000000000000..ab8a0fa2f24773b --- /dev/null +++ b/clang/test/CodeGen/X86/bitscan-builtins.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s + +// PR33722 +// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - | FileCheck %s + +#include + +int test_bit_scan_forward(int a) { +// CHECK-LABEL: test_bit_scan_forward +// CHECK: %[[call:.*]] = call noundef i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true) +// CHECK: ret i32 %[[call]] + return _bit_scan_forward(a); +} + +int test_bit_scan_reverse(int a) { +// CHECK-LABEL: test_bit_scan_reverse +// CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true) +// CHECK: %[[sub:.*]] = sub nsw i32 31, %[[call]] +// CHECK: ret i32 %[[sub]] + return _bit_scan_reverse(a); +} + +int test__bsfd(int X) { +// CHECK-LABEL: test__bsfd +// CHECK: %[[call:.*]] = call noundef i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true) + return __bsfd(X); +} + +int test__bsfq(long long X) { +// CHECK-LABEL: test__bsfq +// CHECK: %[[call:.*]] = call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 true) + return __bsfq(X); +} + +int test__bsrd(int X) { +// CHECK-LABEL: test__bsrd +// CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true) +// CHECK: %[[sub:.*]] = sub nsw i32 31, %[[call]] + return __bsrd(X); +} + +int test__bsrq(long long X) { +// CHECK-LABEL: test__bsrq +// CHECK: %[[call:.*]] = call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 true) +// CHECK: %[[cast:.*]] = trunc i64 %[[call]] to i32 +// CHECK: %[[sub:.*]] = sub nsw i32 63, %[[cast]] + return __bsrq(X); +} + +// Test constexpr handling. +#if defined(__cplusplus) && (__cplusplus >= 201103L) + +char bsf_0[_bit_scan_forward(0x00000001) == 0 ? 1 : -1]; +char bsf_1[_bit_scan_forward(0x10000000) == 28 ? 1 : -1]; + +char bsr_0[_bit_scan_reverse(0x00000001) == 0 ? 1 : -1]; +char bsr_1[_bit_scan_reverse(0x01000000) == 24 ? 1 : -1]; + +char bsfd_0[__bsfd(0x00000008) == 3 ? 1 : -1]; +char bsfd_1[__bsfd(0x00010008) == 3 ? 1 : -1]; + +char bsrd_0[__bsrd(0x00000010) == 4 ? 1 : -1]; +char bsrd_1[__bsrd(0x00100100) == 20 ? 1 : -1]; + +char bsfq_0[__bsfq(0x0000000800000000ULL) == 35 ? 1 : -1]; +char bsfq_1[__bsfq(0x0004000000000000ULL) == 50 ? 1 : -1]; + +char bsrq_0[__bsrq(0x0000100800000000ULL) == 44 ? 1 : -1]; +char bsrq_1[__bsrq(0x0004000100000000ULL) == 50 ? 1 : -1]; + +#endif diff --git a/clang/test/CodeGen/X86/popcnt-builtins.c b/clang/test/CodeGen/X86/popcnt-builtins.c index e59ffaa031a6a10..b9bc666a1e28ad2 100644 --- a/clang/test/CodeGen/X86/popcnt-builtins.c +++ b/clang/test/CodeGen/X86/popcnt-builtins.c @@ -1,7 +1,5 @@ // RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT // RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s #include diff --git a/clang/test/CodeGen/X86/popcnt-builtins.cpp b/clang/test/CodeGen/X86/popcnt-builtins.cpp new file mode 100644 index 000000000000000..42996c547e0af9b --- /dev/null +++ b/clang/test/CodeGen/X86/popcnt-builtins.cpp @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s + +#include + +#ifdef __POPCNT__ +int test_mm_popcnt_u32(unsigned int __X) { + //CHECK-POPCNT: call noundef i32 @llvm.ctpop.i32 + return _mm_popcnt_u32(__X); +} +#endif + +int test_popcnt32(unsigned int __X) { + //CHECK: call noundef i32 @llvm.ctpop.i32 + return _popcnt32(__X); +} + +int test__popcntd(unsigned int __X) { + //CHECK: call noundef i32 @llvm.ctpop.i32 + return __popcntd(__X); +} + +#ifdef __x86_64__ +#ifdef __POPCNT__ +long long test_mm_popcnt_u64(unsigned long long __X) { + //CHECK-POPCNT: call i64 @llvm.ctpop.i64 + return _mm_popcnt_u64(__X); +} +#endif + +long long test_popcnt64(unsigned long long __X) { + //CHECK: call i64 @llvm.ctpop.i64 + return _popcnt64(__X); +} + +long long test__popcntq(unsigned long long __X) { + //CHECK: call i64 @llvm.ctpop.i64 + return __popcntq(__X); +} +#endif + +// Test constexpr handling. +#if defined(__cplusplus) && (__cplusplus >= 201103L) +#if defined(__POPCNT__) +char ctpop32_0[_mm_popcnt_u32(0x00000000) == 0 ? 1 : -1]; +char ctpop32_1[_mm_popcnt_u32(0x000000F0) == 4 ? 1 : -1]; +#endif + +char popcnt32_0[_popcnt32(0x00000000) == 0 ? 1 : -1]; +char popcnt32_1[_popcnt32(0x100000F0) == 5 ? 1 : -1]; + +char popcntd_0[__popcntd(0x00000000) == 0 ? 1 : -1]; +char popcntd_1[__popcntd(0x00F000F0) == 8 ? 1 : -1]; + +#ifdef __x86_64__ +#if defined(__POPCNT__) +char ctpop64_0[_mm_popcnt_u64(0x0000000000000000ULL) == 0 ? 1 : -1]; +char ctpop64_1[_mm_popcnt_u64(0xF000000000000001ULL) == 5 ? 1 : -1]; +#endif + +char popcnt64_0[_popcnt64(0x0000000000000000ULL) == 0 ? 1 : -1]; +char popcnt64_1[_popcnt64(0xF00000F000000001ULL) == 9 ? 1 : -1]; + +char popcntq_0[__popcntq(0x0000000000000000ULL) == 0 ? 1 : -1]; +char popcntq_1[__popcntq(0xF000010000300001ULL) == 8 ? 1 : -1]; +#endif +#endif diff --git a/clang/test/CodeGen/X86/rot-intrinsics.c b/clang/test/CodeGen/X86/rot-intrinsics.c index f8c78119a1c4a77..70bda329ce860c9 100644 --- a/clang/test/CodeGen/X86/rot-intrinsics.c +++ b/clang/test/CodeGen/X86/rot-intrinsics.c @@ -5,13 +5,6 @@ // RUN: %clang_cc1 -x c -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG // RUN: %clang_cc1 -x c -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple i686--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple x86_64--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG - #include unsigned char test__rolb(unsigned char value, int shift) { diff --git a/clang/test/CodeGen/X86/rot-intrinsics.cpp b/clang/test/CodeGen/X86/rot-intrinsics.cpp new file mode 100644 index 000000000000000..90afa91f335e83d --- /dev/null +++ b/clang/test/CodeGen/X86/rot-intrinsics.cpp @@ -0,0 +1,165 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple i686--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-NO-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding -triple x86_64--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-NO-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-NO-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-COMPAT17 +// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG-COMPAT17 + +#include + +unsigned char test__rolb(unsigned char value, int shift) { +// CHECK-LABEL: test__rolb +// CHECK: [[R:%.*]] = call noundef i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]]) +// CHECK: ret i8 [[R]] + return __rolb(value, shift); +} + +unsigned short test__rolw(unsigned short value, int shift) { +// CHECK-LABEL: test__rolw +// CHECK: [[R:%.*]] = call noundef i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]]) +// CHECK: ret i16 [[R]] + return __rolw(value, shift); +} + +unsigned int test__rold(unsigned int value, int shift) { +// CHECK-LABEL: test__rold +// CHECK: [[R:%.*]] = call noundef i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK: ret i32 [[R]] + return __rold(value, shift); +} + +#if defined(__x86_64__) +unsigned long test__rolq(unsigned long value, int shift) { +// CHECK-LONG-LABEL: test__rolq +// CHECK-LONG: [[R:%.*]] = call i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]]) +// CHECK-LONG: ret i64 [[R]] + return __rolq(value, shift); +} +#endif + +unsigned char test__rorb(unsigned char value, int shift) { +// CHECK-LABEL: test__rorb +// CHECK: [[R:%.*]] = call noundef i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]]) +// CHECK: ret i8 [[R]] + return __rorb(value, shift); +} + +unsigned short test__rorw(unsigned short value, int shift) { +// CHECK-LABEL: test__rorw +// CHECK: [[R:%.*]] = call noundef i16 @llvm.fshr.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]]) +// CHECK: ret i16 [[R]] + return __rorw(value, shift); +} + +unsigned int test__rord(unsigned int value, int shift) { +// CHECK-LABEL: test__rord +// CHECK: [[R:%.*]] = call noundef i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK: ret i32 [[R]] + return __rord(value, shift); +} + +#if defined(__x86_64__) +unsigned long test__rorq(unsigned long value, int shift) { +// CHECK-LONG-LABEL: test__rorq +// CHECK-LONG: [[R:%.*]] = call i64 @llvm.fshr.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]]) +// CHECK-LONG: ret i64 [[R]] + return __rorq(value, shift); +} +#endif + +unsigned short test_rotwl(unsigned short value, int shift) { +// CHECK-LABEL: test_rotwl +// CHECK: [[R:%.*]] = call noundef i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]]) +// CHECK: ret i16 [[R]] + return _rotwl(value, shift); +} + +unsigned int test_rotl(unsigned int value, int shift) { +// CHECK-32BIT-LONG-COMPAT17-LABEL: test_rotl +// CHECK-32BIT-LONG-COMPAT17: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-COMPAT17: ret i32 [[R]] +// +// CHECK-32BIT-LONG-NO-COMPAT17-LABEL: test_rotl +// CHECK-32BIT-LONG-NO-COMPAT17: [[R:%.*]] = call noundef i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-NO-COMPAT17: ret i32 [[R]] + return _rotl(value, shift); +} + +unsigned long test_lrotl(unsigned long value, int shift) { +// CHECK-32BIT-LONG-COMPAT17-LABEL: test_lrotl +// CHECK-32BIT-LONG-COMPAT17: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-COMPAT17: ret i32 [[R]] +// +// CHECK-32BIT-LONG-NO-COMPAT17-LABEL: test_lrotl +// CHECK-32BIT-LONG-NO-COMPAT17: [[R:%.*]] = call noundef i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]]) +// CHECK-32BIT-LONG-NO-COMPAT17: ret i32 [[R]] +// +// CHECK-64BIT-LONG-LABEL: test_lrotl +// CHECK-64BIT-LONG: [[R:%.*]] = call noundef i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]]) +// CHECK-64BIT-LONG: ret i64 [[R]] + return _lrotl(value, shift); +} + + +unsigned short test_ro... |
3c86063 to a97fe92 Compare | Compile time impact: https://llvm-compile-time-tracker.com/compare.php?from=825df6cfeae3b3aeaa3e8a1882c564bc50d99be5&to=4ccda9426371d37d57042058992931e3bd1ea9e3&stat=instructions:u Some regression for ThinLTO/FullLTO, minimal for normal O3 build. |
Why was this necessary? |
Different |
a97fe92 to 4842b27 Compare | It occurs to me that the current return attribute propagation is currently buggy for poison-generating attributes: https://llvm.godbolt.org/z/x8n18q9Mj In this case the argument to use() will now be poison as well, while before inlining only the return value was poison. This code needs to distinguish poison and UB generating attributes. |
Good catch. I think this means basically |
Limiting poison-generating attributes to one-use while keeping the rest of the logic (with guarantee-to-transfer) would be the simplest way to make the existing code correct. There are two additional ways to generalize:
|
I.e: If we add
Oh I see, you mean something like: So it would convert We also need to be careful about transferring the I think with one-use + guranteed to transfer (the latter is a precondition for transferring at all) |
Yes, this is fine, because the UB will be hit anyway. We can move it backwards, as long as it's guaranteed to execute.
You are right, the former case isn't correct even with one-use to guaranteed-to-transfer. That case would only work if we also had noundef on the foo return value. |
@nikic, on the former case, could we just strip |
4842b27 to 91857a5 Compare | ``
Fixed with new commit ( |
| I don't think 10 commit PRs are helpful. This should be 3 PRs at least. One is trivial, one is probably easy, and then one with the new stuff. |
So PR based on PR? The thing is there are dependencies between commits. |
We always had dependences between commits. Just mention it in the commit message. |
91857a5 to dcf3aa0 Compare
Okay, I can't really see a reasonable way to create a proper series. I am going to submit this piece-meal. |
nikic left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Second commit is missing test diffs -- either tests are missing or improperly committed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this do anything useful over a hasOneUse check? We only allow the case where the call and return are in the same block, so there can only be one ReturnInst user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not at the moment, I guess my feeling is we would like to be able to handle uses that can't cause UB (something like an ptrmask use) which will require looping. Secondly, this seems more "correct" should our constraints above change, and will be roughly the same cost as hasOneUse in the meantime (will be at most 2 iter).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See caller12_todo test as an example of what we should be able to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO we should only introduce this loop once it actually does something useful. For now this is just confusing dead code.
dcf3aa0 to cc55e56 Compare
Sorry, had gotten messed up when splitting. Fixed. |
| ✅ With the latest revision this PR passed the C/C++ code formatter. |
cc55e56 to cc04dc3 Compare
nikic left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I would write this either as
| bool Okay = true; | |
| if (!CB.hasRetAttr(Attribute::NoUndef)) { | |
| // Cover case 3 where introducing a poison generating attribute can | |
| // cause immediate UB. | |
| Okay = !RetVal->hasRetAttr(Attribute::NoUndef); | |
| // This is an overly conservative way to check that there are no other | |
| // uses whose behavior may change/may introduce UB if we potentially | |
| // return poison. | |
| // TODO: Iterative through uses and only bail if we have a potentially | |
| // dangerous use. | |
| Okay &= RetVal->hasOneUse(); | |
| } | |
| if (Okay) | |
| // Comments... | |
| if (CB.hasRetAttr(Attribute::NoUndef) || | |
| (!RetVal->hasRetAttr(Attribute::NoUndef) && RetVal->hasOneUse())) |
or move it into a function with early returns, rather than using an Okay flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, although imo it makes the comments a bit more difficult to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Iterate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dso_local shouldn't be needed.
Poison generating return attributes can't be propagated the same as others, as they can change the behavior of other uses and/or create UB where it otherwise wouldn't have occurred. For example: ``` define nonnull ptr @foo() { %p = call ptr @bar() call void @use(ptr %p) ret ptr %p } ``` If we inline `@foo` and propagate `nonnull` to `@bar`, it could change the behavior of `@use` as instead of taking `null`, `@use` will now be passed `poison`. This can be even worth in a case like: ``` define nonnull ptr @foo() { %p = call noundef ptr @bar() ret ptr %p } ``` Where propagating `nonnull` to `@bar` will cause UB on `null` return of `@bar` (`noundef` + `poison`) where it previously wouldn't have occurred. To fix this, we only propagate poison generating return attributes if either 1) The only use of the callsite to propagate too is return and the callsite to propagate too doesn't have `noundef`. Or 2) the callsite to be be inlined has `noundef`. The former case ensures no new UB or `poison` values will be added. The latter is UB anyways if the value is `poison` so we can go ahead without worrying about behavior changes.
cc04dc3 to 76331bc Compare | Pushed. |
[Inliner] Fix bug when propagating poison generating return attributes
Poison generating return attributes can't be propagated the same as
others, as they can change the behavior of other uses and/or create UB
where it otherwise wouldn't have occurred.
For example:
If we inline
@fooand propagatenonnullto@bar, it could changethe behavior of
@useas instead of takingnull,@usewillnow be passed
poison.This can be even worth in a case like:
Where propagating
nonnullto@barwill cause UB onnullreturnof
@bar(noundef+poison) where it previously wouldn'thave occurred.
To fix this, we only propagate poison generating return attributes if
either 1) The only use of the callsite to propagate too is return and
the callsite to propagate too doesn't have
noundef. Or 2) thecallsite to be be inlined has
noundef.The former case ensures no new UB or
poisonvalues will beadded. The latter is UB anyways if the value is
poisonso we can goahead without worrying about behavior changes.