[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/94352 >From ff839bef048a65760f4cd0e9abafe11cfebd9362 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 21:08:27 +0800 Subject: [PATCH 1/8] [RISCV] Add support for getHostCPUFeatures using hwprobe Co-authored-by: Yangyu Chen --- llvm/lib/TargetParser/Host.cpp | 68 ++ 1 file changed, 68 insertions(+) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 68155acd9e5bc..b4a13b38eb380 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1998,6 +1998,74 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +#ifdef __has_include +#if __has_include() +#include +#endif +#endif +bool sys::getHostCPUFeatures(StringMap &Features) { +#ifdef RISCV_HWPROBE_KEY_MVENDORID + riscv_hwprobe Query[2]{ + {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, + {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, + }; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, +/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + if (Ret != 0) +return false; + + uint64_t ExtMask = Query[0].value; + Features["f"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["d"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["c"] = ExtMask & RISCV_HWPROBE_IMA_C; + Features["v"] = ExtMask & RISCV_HWPROBE_IMA_V; + Features["zba"] = ExtMask & RISCV_HWPROBE_IMA_ZBA; + Features["zbb"] = ExtMask & RISCV_HWPROBE_IMA_ZBB; + Features["zbs"] = ExtMask & RISCV_HWPROBE_IMA_ZBS; + Features["zicboz"] = ExtMask & RISCV_HWPROBE_IMA_ZICBOZ; + Features["zbc"] = ExtMask & RISCV_HWPROBE_IMA_ZBC; + Features["zbkb"] = ExtMask & RISCV_HWPROBE_IMA_ZBKB; + Features["zbkc"] = ExtMask & RISCV_HWPROBE_IMA_ZBKC; + Features["zbkx"] = ExtMask & RISCV_HWPROBE_IMA_ZBKX; + Features["zknd"] = ExtMask & RISCV_HWPROBE_IMA_ZKND; + Features["zkne"] = ExtMask & RISCV_HWPROBE_IMA_ZKNE; + Features["zknh"] = ExtMask & RISCV_HWPROBE_IMA_ZKNH; + Features["zksed"] = ExtMask & RISCV_HWPROBE_IMA_ZKSED; + Features["zksh"] = ExtMask & RISCV_HWPROBE_IMA_ZKSH; + Features["zkt"] = ExtMask & RISCV_HWPROBE_IMA_ZKT; + Features["zvbb"] = ExtMask & RISCV_HWPROBE_IMA_ZVBB; + Features["zvbc"] = ExtMask & RISCV_HWPROBE_IMA_ZVBC; + Features["zvkb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKB; + Features["zvkg"] = ExtMask & RISCV_HWPROBE_IMA_ZVKG; + Features["zvkned"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNED; + Features["zvknha"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHA; + Features["zvknhb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHB; + Features["zvksed"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSED; + Features["zvksh"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSH; + Features["zvkt"] = ExtMask & RISCV_HWPROBE_IMA_ZVKT; + Features["zfh"] = ExtMask & RISCV_HWPROBE_IMA_ZFH; + Features["zfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZFHMIN; + Features["zihintntl"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTNTL; + Features["zvfh"] = ExtMask & RISCV_HWPROBE_IMA_ZVFH; + Features["zvfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZVFHMIN; + Features["zfa"] = ExtMask & RISCV_HWPROBE_IMA_ZFA; + Features["ztso"] = ExtMask & RISCV_HWPROBE_IMA_ZTSO; + Features["zacas"] = ExtMask & RISCV_HWPROBE_IMA_ZACAS; + Features["zicond"] = ExtMask & RISCV_HWPROBE_IMA_ZICOND; + Features["zihintpause"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTPAUSE; + + uint64_t MisalignedMask = Query[1].value; + if (MisalignedMask == RISCV_HWPROBE_MISALIGNED_FAST) { +Features["unaligned-scalar-mem"] = true; +Features["unaligned-vector-mem"] = true; + } + + return true; +#else + return false; +#endif +} #else bool sys::getHostCPUFeatures(StringMap &Features) { return false; } #endif >From a2fa6e3d64d3a1e2a8e3a7af91068bdb1fda28b1 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 22:10:55 +0800 Subject: [PATCH 2/8] [RISCV] Address review comments. --- llvm/lib/TargetParser/Host.cpp | 112 +++-- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index b4a13b38eb380..ec275c0a7fded 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1999,72 +1999,64 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } #elif defined(__linux__) && defined(__riscv) -#ifdef __has_include -#if __has_include() -#include -#endif -#endif +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; bool sys::getHostCPUFeatures(StringMap &Features) { -#ifdef RISCV_HWPROBE_KEY_MVENDORID - riscv_hwprobe Query[2]{ - {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, - {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, - }; - int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, -/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + int Re
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/94352 >From ff839bef048a65760f4cd0e9abafe11cfebd9362 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 21:08:27 +0800 Subject: [PATCH 1/9] [RISCV] Add support for getHostCPUFeatures using hwprobe Co-authored-by: Yangyu Chen --- llvm/lib/TargetParser/Host.cpp | 68 ++ 1 file changed, 68 insertions(+) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 68155acd9e5bc..b4a13b38eb380 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1998,6 +1998,74 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +#ifdef __has_include +#if __has_include() +#include +#endif +#endif +bool sys::getHostCPUFeatures(StringMap &Features) { +#ifdef RISCV_HWPROBE_KEY_MVENDORID + riscv_hwprobe Query[2]{ + {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, + {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, + }; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, +/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + if (Ret != 0) +return false; + + uint64_t ExtMask = Query[0].value; + Features["f"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["d"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["c"] = ExtMask & RISCV_HWPROBE_IMA_C; + Features["v"] = ExtMask & RISCV_HWPROBE_IMA_V; + Features["zba"] = ExtMask & RISCV_HWPROBE_IMA_ZBA; + Features["zbb"] = ExtMask & RISCV_HWPROBE_IMA_ZBB; + Features["zbs"] = ExtMask & RISCV_HWPROBE_IMA_ZBS; + Features["zicboz"] = ExtMask & RISCV_HWPROBE_IMA_ZICBOZ; + Features["zbc"] = ExtMask & RISCV_HWPROBE_IMA_ZBC; + Features["zbkb"] = ExtMask & RISCV_HWPROBE_IMA_ZBKB; + Features["zbkc"] = ExtMask & RISCV_HWPROBE_IMA_ZBKC; + Features["zbkx"] = ExtMask & RISCV_HWPROBE_IMA_ZBKX; + Features["zknd"] = ExtMask & RISCV_HWPROBE_IMA_ZKND; + Features["zkne"] = ExtMask & RISCV_HWPROBE_IMA_ZKNE; + Features["zknh"] = ExtMask & RISCV_HWPROBE_IMA_ZKNH; + Features["zksed"] = ExtMask & RISCV_HWPROBE_IMA_ZKSED; + Features["zksh"] = ExtMask & RISCV_HWPROBE_IMA_ZKSH; + Features["zkt"] = ExtMask & RISCV_HWPROBE_IMA_ZKT; + Features["zvbb"] = ExtMask & RISCV_HWPROBE_IMA_ZVBB; + Features["zvbc"] = ExtMask & RISCV_HWPROBE_IMA_ZVBC; + Features["zvkb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKB; + Features["zvkg"] = ExtMask & RISCV_HWPROBE_IMA_ZVKG; + Features["zvkned"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNED; + Features["zvknha"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHA; + Features["zvknhb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHB; + Features["zvksed"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSED; + Features["zvksh"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSH; + Features["zvkt"] = ExtMask & RISCV_HWPROBE_IMA_ZVKT; + Features["zfh"] = ExtMask & RISCV_HWPROBE_IMA_ZFH; + Features["zfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZFHMIN; + Features["zihintntl"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTNTL; + Features["zvfh"] = ExtMask & RISCV_HWPROBE_IMA_ZVFH; + Features["zvfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZVFHMIN; + Features["zfa"] = ExtMask & RISCV_HWPROBE_IMA_ZFA; + Features["ztso"] = ExtMask & RISCV_HWPROBE_IMA_ZTSO; + Features["zacas"] = ExtMask & RISCV_HWPROBE_IMA_ZACAS; + Features["zicond"] = ExtMask & RISCV_HWPROBE_IMA_ZICOND; + Features["zihintpause"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTPAUSE; + + uint64_t MisalignedMask = Query[1].value; + if (MisalignedMask == RISCV_HWPROBE_MISALIGNED_FAST) { +Features["unaligned-scalar-mem"] = true; +Features["unaligned-vector-mem"] = true; + } + + return true; +#else + return false; +#endif +} #else bool sys::getHostCPUFeatures(StringMap &Features) { return false; } #endif >From a2fa6e3d64d3a1e2a8e3a7af91068bdb1fda28b1 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 22:10:55 +0800 Subject: [PATCH 2/9] [RISCV] Address review comments. --- llvm/lib/TargetParser/Host.cpp | 112 +++-- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index b4a13b38eb380..ec275c0a7fded 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1999,72 +1999,64 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } #elif defined(__linux__) && defined(__riscv) -#ifdef __has_include -#if __has_include() -#include -#endif -#endif +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; bool sys::getHostCPUFeatures(StringMap &Features) { -#ifdef RISCV_HWPROBE_KEY_MVENDORID - riscv_hwprobe Query[2]{ - {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, - {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, - }; - int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, -/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + int Re
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
dtcxzyw wrote: > > I have no idea about why it corrupts StringMap. Sad :( > > ![image](https://private-user-images.githubusercontent.com/15650457/341986439-fd427068-6ca0-4ecb-a340-48c51e5629a6.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTkyMTE0NzgsIm5iZiI6MTcxOTIxMTE3OCwicGF0aCI6Ii8xNTY1MDQ1Ny8zNDE5ODY0MzktZmQ0MjcwNjgtNmNhMC00ZWNiLWEzNDAtNDhjNTFlNTYyOWE2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI0VDA2MzkzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQ3MzBjMmIwNGNhYmM3NmZiNjJiZWFmMTRhNmQ3MWM1Y2I4NGE2NGFjY2RhZDIwNGJmN2Q2MzUyYmI5NzI2OTgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.z46AIxQBdVWJ2Z6xGXCA_5v54-NU9KwydxMTUHXxuRo) > > Is this fixed after fixing the return statement? This may be caused by the > corruption of `getHostCPUNameForRISCV`. ![image](https://github.com/llvm/llvm-project/assets/15650457/50a094d6-c866-40ae-a693-d3964ef435a3) It works well now :) I will post a patch removing experimental from `ztso`. https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Remove experimental from Ztso. (PR #96465)
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/96465 Ztso 1.0 was ratified in January 2023. Documentation: https://github.com/riscv/riscv-isa-manual/blob/main/src/ztso-st-ext.adoc >From 34670ab55ccecb1a2c7d92f809c9cae0df4150c6 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 24 Jun 2024 16:43:04 +0800 Subject: [PATCH] [RISCV] Remove experimental from Ztso. --- clang/test/Driver/riscv-arch.c| 24 ++ .../test/Preprocessor/riscv-target-features.c | 10 ++-- llvm/docs/RISCVUsage.rst | 4 +- llvm/docs/ReleaseNotes.rst| 1 + llvm/lib/Target/RISCV/RISCVFeatures.td| 4 +- .../CodeGen/RISCV/GlobalISel/atomic-fence.ll | 4 +- llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll | 10 ++-- llvm/test/CodeGen/RISCV/atomic-fence.ll | 4 +- llvm/test/CodeGen/RISCV/atomic-load-store.ll | 8 ++-- llvm/test/CodeGen/RISCV/atomic-rmw.ll | 12 ++--- .../CodeGen/RISCV/atomicrmw-uinc-udec-wrap.ll | 4 +- llvm/test/CodeGen/RISCV/attributes.ll | 4 +- llvm/test/CodeGen/RISCV/module-elf-flags.ll | 2 +- llvm/test/MC/RISCV/Ztso.s | 4 +- llvm/test/MC/RISCV/attribute-arch.s | 4 +- llvm/test/MC/RISCV/elf-flags.s| 4 +- .../TargetParser/RISCVISAInfoTest.cpp | 46 +-- 17 files changed, 77 insertions(+), 72 deletions(-) diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c index ffd92e1f398c4..c3c471c4bc396 100644 --- a/clang/test/Driver/riscv-arch.c +++ b/clang/test/Driver/riscv-arch.c @@ -365,24 +365,30 @@ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ZFHMIN %s // RV32-ZFHMIN: "-target-feature" "+zfhmin" -// RUN: not %clang --target=riscv32-unknown-elf -march=rv32iztso -### %s \ +// RUN: not %clang --target=riscv32-unknown-elf -march=rv32izalasr -### %s \ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-NOFLAG %s -// RV32-EXPERIMENTAL-NOFLAG: error: invalid arch name 'rv32iztso' +// RV32-EXPERIMENTAL-NOFLAG: error: invalid arch name 'rv32izalasr' // RV32-EXPERIMENTAL-NOFLAG: requires '-menable-experimental-extensions' -// RUN: not %clang --target=riscv32-unknown-elf -march=rv32iztso -menable-experimental-extensions -### %s \ +// RUN: not %clang --target=riscv32-unknown-elf -march=rv32izalasr -menable-experimental-extensions -### %s \ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-NOVERS %s -// RV32-EXPERIMENTAL-NOVERS: error: invalid arch name 'rv32iztso' +// RV32-EXPERIMENTAL-NOVERS: error: invalid arch name 'rv32izalasr' // RV32-EXPERIMENTAL-NOVERS: experimental extension requires explicit version number -// RUN: not %clang --target=riscv32-unknown-elf -march=rv32iztso0p7 -menable-experimental-extensions -### %s \ +// RUN: not %clang --target=riscv32-unknown-elf -march=rv32izalasr0p7 -menable-experimental-extensions -### %s \ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-BADVERS %s -// RV32-EXPERIMENTAL-BADVERS: error: invalid arch name 'rv32iztso0p7' -// RV32-EXPERIMENTAL-BADVERS: unsupported version number 0.7 for experimental extension 'ztso' (this compiler supports 0.1) +// RV32-EXPERIMENTAL-BADVERS: error: invalid arch name 'rv32izalasr0p7' +// RV32-EXPERIMENTAL-BADVERS: unsupported version number 0.7 for experimental extension 'zalasr' (this compiler supports 0.1) -// RUN: %clang --target=riscv32-unknown-elf -march=rv32iztso0p1 -menable-experimental-extensions -### %s \ +// RUN: %clang --target=riscv32-unknown-elf -march=rv32izalasr0p1 -menable-experimental-extensions -### %s \ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-GOODVERS %s -// RV32-EXPERIMENTAL-GOODVERS: "-target-feature" "+experimental-ztso" +// RV32-EXPERIMENTAL-GOODVERS: "-target-feature" "+experimental-zalasr" + +// RUN: %clang --target=riscv32-unknown-elf -march=rv32iztso1p0 -### %s \ +// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ZTSO %s +// RUN: %clang --target=riscv32-unknown-elf -march=rv32iztso -### %s \ +// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ZTSO %s +// RV32-ZTSO: "-target-feature" "+ztso" // RUN: %clang --target=riscv32-unknown-elf -march=rv32izbb1p0 -### %s \ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ZBB %s diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index d7935af532dfa..46a61e3c0afc7 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -1650,13 +1650,13 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-ZICFILP-EXT %s // CHECK-ZICFILP-EXT: __riscv_zicfilp 4000{{$}} -// RUN: %clang --target=riscv32-unknown-linux-gnu -menable-experimental-extensions \ -// RUN: -march=rv32iztso0p1 -E -dM %s \ +// RUN: %clang --target=riscv32-unknown-linux-gnu \ +// RUN: -march=rv32iztso1p0 -E -dM %s \ // R
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
dtcxzyw wrote: See https://github.com/llvm/llvm-project/pull/96465 https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Remove experimental from Ztso. (PR #96465)
@@ -365,24 +365,30 @@ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ZFHMIN %s // RV32-ZFHMIN: "-target-feature" "+zfhmin" -// RUN: not %clang --target=riscv32-unknown-elf -march=rv32iztso -### %s \ +// RUN: not %clang --target=riscv32-unknown-elf -march=rv32izalasr -### %s \ dtcxzyw wrote: Yeah. https://github.com/llvm/llvm-project/pull/96465 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Remove experimental from Ztso. (PR #96465)
https://github.com/dtcxzyw closed https://github.com/llvm/llvm-project/pull/96465 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/94352 >From ff839bef048a65760f4cd0e9abafe11cfebd9362 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 21:08:27 +0800 Subject: [PATCH 01/10] [RISCV] Add support for getHostCPUFeatures using hwprobe Co-authored-by: Yangyu Chen --- llvm/lib/TargetParser/Host.cpp | 68 ++ 1 file changed, 68 insertions(+) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 68155acd9e5bc..b4a13b38eb380 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1998,6 +1998,74 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +#ifdef __has_include +#if __has_include() +#include +#endif +#endif +bool sys::getHostCPUFeatures(StringMap &Features) { +#ifdef RISCV_HWPROBE_KEY_MVENDORID + riscv_hwprobe Query[2]{ + {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, + {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, + }; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, +/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + if (Ret != 0) +return false; + + uint64_t ExtMask = Query[0].value; + Features["f"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["d"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["c"] = ExtMask & RISCV_HWPROBE_IMA_C; + Features["v"] = ExtMask & RISCV_HWPROBE_IMA_V; + Features["zba"] = ExtMask & RISCV_HWPROBE_IMA_ZBA; + Features["zbb"] = ExtMask & RISCV_HWPROBE_IMA_ZBB; + Features["zbs"] = ExtMask & RISCV_HWPROBE_IMA_ZBS; + Features["zicboz"] = ExtMask & RISCV_HWPROBE_IMA_ZICBOZ; + Features["zbc"] = ExtMask & RISCV_HWPROBE_IMA_ZBC; + Features["zbkb"] = ExtMask & RISCV_HWPROBE_IMA_ZBKB; + Features["zbkc"] = ExtMask & RISCV_HWPROBE_IMA_ZBKC; + Features["zbkx"] = ExtMask & RISCV_HWPROBE_IMA_ZBKX; + Features["zknd"] = ExtMask & RISCV_HWPROBE_IMA_ZKND; + Features["zkne"] = ExtMask & RISCV_HWPROBE_IMA_ZKNE; + Features["zknh"] = ExtMask & RISCV_HWPROBE_IMA_ZKNH; + Features["zksed"] = ExtMask & RISCV_HWPROBE_IMA_ZKSED; + Features["zksh"] = ExtMask & RISCV_HWPROBE_IMA_ZKSH; + Features["zkt"] = ExtMask & RISCV_HWPROBE_IMA_ZKT; + Features["zvbb"] = ExtMask & RISCV_HWPROBE_IMA_ZVBB; + Features["zvbc"] = ExtMask & RISCV_HWPROBE_IMA_ZVBC; + Features["zvkb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKB; + Features["zvkg"] = ExtMask & RISCV_HWPROBE_IMA_ZVKG; + Features["zvkned"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNED; + Features["zvknha"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHA; + Features["zvknhb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHB; + Features["zvksed"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSED; + Features["zvksh"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSH; + Features["zvkt"] = ExtMask & RISCV_HWPROBE_IMA_ZVKT; + Features["zfh"] = ExtMask & RISCV_HWPROBE_IMA_ZFH; + Features["zfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZFHMIN; + Features["zihintntl"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTNTL; + Features["zvfh"] = ExtMask & RISCV_HWPROBE_IMA_ZVFH; + Features["zvfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZVFHMIN; + Features["zfa"] = ExtMask & RISCV_HWPROBE_IMA_ZFA; + Features["ztso"] = ExtMask & RISCV_HWPROBE_IMA_ZTSO; + Features["zacas"] = ExtMask & RISCV_HWPROBE_IMA_ZACAS; + Features["zicond"] = ExtMask & RISCV_HWPROBE_IMA_ZICOND; + Features["zihintpause"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTPAUSE; + + uint64_t MisalignedMask = Query[1].value; + if (MisalignedMask == RISCV_HWPROBE_MISALIGNED_FAST) { +Features["unaligned-scalar-mem"] = true; +Features["unaligned-vector-mem"] = true; + } + + return true; +#else + return false; +#endif +} #else bool sys::getHostCPUFeatures(StringMap &Features) { return false; } #endif >From a2fa6e3d64d3a1e2a8e3a7af91068bdb1fda28b1 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 22:10:55 +0800 Subject: [PATCH 02/10] [RISCV] Address review comments. --- llvm/lib/TargetParser/Host.cpp | 112 +++-- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index b4a13b38eb380..ec275c0a7fded 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1999,72 +1999,64 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } #elif defined(__linux__) && defined(__riscv) -#ifdef __has_include -#if __has_include() -#include -#endif -#endif +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; bool sys::getHostCPUFeatures(StringMap &Features) { -#ifdef RISCV_HWPROBE_KEY_MVENDORID - riscv_hwprobe Query[2]{ - {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, - {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, - }; - int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, -/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + i
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/94352 >From ff839bef048a65760f4cd0e9abafe11cfebd9362 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 21:08:27 +0800 Subject: [PATCH 01/11] [RISCV] Add support for getHostCPUFeatures using hwprobe Co-authored-by: Yangyu Chen --- llvm/lib/TargetParser/Host.cpp | 68 ++ 1 file changed, 68 insertions(+) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 68155acd9e5bc..b4a13b38eb380 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1998,6 +1998,74 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +#ifdef __has_include +#if __has_include() +#include +#endif +#endif +bool sys::getHostCPUFeatures(StringMap &Features) { +#ifdef RISCV_HWPROBE_KEY_MVENDORID + riscv_hwprobe Query[2]{ + {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, + {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, + }; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, +/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + if (Ret != 0) +return false; + + uint64_t ExtMask = Query[0].value; + Features["f"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["d"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["c"] = ExtMask & RISCV_HWPROBE_IMA_C; + Features["v"] = ExtMask & RISCV_HWPROBE_IMA_V; + Features["zba"] = ExtMask & RISCV_HWPROBE_IMA_ZBA; + Features["zbb"] = ExtMask & RISCV_HWPROBE_IMA_ZBB; + Features["zbs"] = ExtMask & RISCV_HWPROBE_IMA_ZBS; + Features["zicboz"] = ExtMask & RISCV_HWPROBE_IMA_ZICBOZ; + Features["zbc"] = ExtMask & RISCV_HWPROBE_IMA_ZBC; + Features["zbkb"] = ExtMask & RISCV_HWPROBE_IMA_ZBKB; + Features["zbkc"] = ExtMask & RISCV_HWPROBE_IMA_ZBKC; + Features["zbkx"] = ExtMask & RISCV_HWPROBE_IMA_ZBKX; + Features["zknd"] = ExtMask & RISCV_HWPROBE_IMA_ZKND; + Features["zkne"] = ExtMask & RISCV_HWPROBE_IMA_ZKNE; + Features["zknh"] = ExtMask & RISCV_HWPROBE_IMA_ZKNH; + Features["zksed"] = ExtMask & RISCV_HWPROBE_IMA_ZKSED; + Features["zksh"] = ExtMask & RISCV_HWPROBE_IMA_ZKSH; + Features["zkt"] = ExtMask & RISCV_HWPROBE_IMA_ZKT; + Features["zvbb"] = ExtMask & RISCV_HWPROBE_IMA_ZVBB; + Features["zvbc"] = ExtMask & RISCV_HWPROBE_IMA_ZVBC; + Features["zvkb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKB; + Features["zvkg"] = ExtMask & RISCV_HWPROBE_IMA_ZVKG; + Features["zvkned"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNED; + Features["zvknha"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHA; + Features["zvknhb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHB; + Features["zvksed"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSED; + Features["zvksh"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSH; + Features["zvkt"] = ExtMask & RISCV_HWPROBE_IMA_ZVKT; + Features["zfh"] = ExtMask & RISCV_HWPROBE_IMA_ZFH; + Features["zfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZFHMIN; + Features["zihintntl"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTNTL; + Features["zvfh"] = ExtMask & RISCV_HWPROBE_IMA_ZVFH; + Features["zvfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZVFHMIN; + Features["zfa"] = ExtMask & RISCV_HWPROBE_IMA_ZFA; + Features["ztso"] = ExtMask & RISCV_HWPROBE_IMA_ZTSO; + Features["zacas"] = ExtMask & RISCV_HWPROBE_IMA_ZACAS; + Features["zicond"] = ExtMask & RISCV_HWPROBE_IMA_ZICOND; + Features["zihintpause"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTPAUSE; + + uint64_t MisalignedMask = Query[1].value; + if (MisalignedMask == RISCV_HWPROBE_MISALIGNED_FAST) { +Features["unaligned-scalar-mem"] = true; +Features["unaligned-vector-mem"] = true; + } + + return true; +#else + return false; +#endif +} #else bool sys::getHostCPUFeatures(StringMap &Features) { return false; } #endif >From a2fa6e3d64d3a1e2a8e3a7af91068bdb1fda28b1 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 22:10:55 +0800 Subject: [PATCH 02/11] [RISCV] Address review comments. --- llvm/lib/TargetParser/Host.cpp | 112 +++-- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index b4a13b38eb380..ec275c0a7fded 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1999,72 +1999,64 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } #elif defined(__linux__) && defined(__riscv) -#ifdef __has_include -#if __has_include() -#include -#endif -#endif +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; bool sys::getHostCPUFeatures(StringMap &Features) { -#ifdef RISCV_HWPROBE_KEY_MVENDORID - riscv_hwprobe Query[2]{ - {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, - {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, - }; - int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, -/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + i
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
@@ -2002,6 +2003,76 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; +bool sys::getHostCPUFeatures(StringMap &Features) { + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0}, + {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query, +/*pair_count=*/std::size(Query), /*cpu_count=*/0, +/*cpus=*/0, /*flags=*/0); + if (Ret != 0) +return false; + + uint64_t BaseMask = Query[0].Value; + // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set. + if (BaseMask & 1) { +Features["i"] = true; +Features["m"] = true; +Features["a"] = true; + } + + uint64_t ExtMask = Query[1].Value; + Features["f"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD + Features["d"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD + Features["c"] = ExtMask & (1 << 1); // RISCV_HWPROBE_IMA_C + Features["v"] = ExtMask & (1 << 2); // RISCV_HWPROBE_IMA_V + Features["zba"] = ExtMask & (1 << 3); // RISCV_HWPROBE_EXT_ZBA + Features["zbb"] = ExtMask & (1 << 4); // RISCV_HWPROBE_EXT_ZBB + Features["zbs"] = ExtMask & (1 << 5); // RISCV_HWPROBE_EXT_ZBS + Features["zicboz"] = ExtMask & (1 << 6); // RISCV_HWPROBE_EXT_ZICBOZ + Features["zbc"] = ExtMask & (1 << 7); // RISCV_HWPROBE_EXT_ZBC + Features["zbkb"] = ExtMask & (1 << 8);// RISCV_HWPROBE_EXT_ZBKB + Features["zbkc"] = ExtMask & (1 << 9);// RISCV_HWPROBE_EXT_ZBKC + Features["zbkx"] = ExtMask & (1 << 10); // RISCV_HWPROBE_EXT_ZBKX + Features["zknd"] = ExtMask & (1 << 11); // RISCV_HWPROBE_EXT_ZKND + Features["zkne"] = ExtMask & (1 << 12); // RISCV_HWPROBE_EXT_ZKNE + Features["zknh"] = ExtMask & (1 << 13); // RISCV_HWPROBE_EXT_ZKNH + Features["zksed"] = ExtMask & (1 << 14); // RISCV_HWPROBE_EXT_ZKSED + Features["zksh"] = ExtMask & (1 << 15); // RISCV_HWPROBE_EXT_ZKSH + Features["zkt"] = ExtMask & (1 << 16);// RISCV_HWPROBE_EXT_ZKT + Features["zvbb"] = ExtMask & (1 << 17); // RISCV_HWPROBE_EXT_ZVBB + Features["zvbc"] = ExtMask & (1 << 18); // RISCV_HWPROBE_EXT_ZVBC + Features["zvkb"] = ExtMask & (1 << 19); // RISCV_HWPROBE_EXT_ZVKB + Features["zvkg"] = ExtMask & (1 << 20); // RISCV_HWPROBE_EXT_ZVKG + Features["zvkned"] = ExtMask & (1 << 21); // RISCV_HWPROBE_EXT_ZVKNED + Features["zvknha"] = ExtMask & (1 << 22); // RISCV_HWPROBE_EXT_ZVKNHA + Features["zvknhb"] = ExtMask & (1 << 23); // RISCV_HWPROBE_EXT_ZVKNHB + Features["zvksed"] = ExtMask & (1 << 24); // RISCV_HWPROBE_EXT_ZVKSED + Features["zvksh"] = ExtMask & (1 << 25); // RISCV_HWPROBE_EXT_ZVKSH + Features["zvkt"] = ExtMask & (1 << 26); // RISCV_HWPROBE_EXT_ZVKT + Features["zfh"] = ExtMask & (1 << 27);// RISCV_HWPROBE_EXT_ZFH + Features["zfhmin"] = ExtMask & (1 << 28); // RISCV_HWPROBE_EXT_ZFHMIN + Features["zihintntl"] = ExtMask & (1 << 29); // RISCV_HWPROBE_EXT_ZIHINTNTL + Features["zvfh"] = ExtMask & (1 << 30); // RISCV_HWPROBE_EXT_ZVFH + Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN + Features["zfa"] = ExtMask & (1ULL << 32); // RISCV_HWPROBE_EXT_ZFA + // TODO: set ztso when it is no longer experimental. + // Features["ztso"] = ExtMask & (1ULL << 33);// RISCV_HWPROBE_EXT_ZTSO dtcxzyw wrote: @topperc @preames What do you think about the ztso support as a todo? https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
https://github.com/dtcxzyw edited https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
@@ -2002,6 +2003,76 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; +bool sys::getHostCPUFeatures(StringMap &Features) { + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0}, + {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query, +/*pair_count=*/std::size(Query), /*cpu_count=*/0, +/*cpus=*/0, /*flags=*/0); + if (Ret != 0) +return false; + + uint64_t BaseMask = Query[0].Value; + // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set. + if (BaseMask & 1) { +Features["i"] = true; +Features["m"] = true; +Features["a"] = true; + } + + uint64_t ExtMask = Query[1].Value; + Features["f"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD + Features["d"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD + Features["c"] = ExtMask & (1 << 1); // RISCV_HWPROBE_IMA_C + Features["v"] = ExtMask & (1 << 2); // RISCV_HWPROBE_IMA_V + Features["zba"] = ExtMask & (1 << 3); // RISCV_HWPROBE_EXT_ZBA + Features["zbb"] = ExtMask & (1 << 4); // RISCV_HWPROBE_EXT_ZBB + Features["zbs"] = ExtMask & (1 << 5); // RISCV_HWPROBE_EXT_ZBS + Features["zicboz"] = ExtMask & (1 << 6); // RISCV_HWPROBE_EXT_ZICBOZ + Features["zbc"] = ExtMask & (1 << 7); // RISCV_HWPROBE_EXT_ZBC + Features["zbkb"] = ExtMask & (1 << 8);// RISCV_HWPROBE_EXT_ZBKB + Features["zbkc"] = ExtMask & (1 << 9);// RISCV_HWPROBE_EXT_ZBKC + Features["zbkx"] = ExtMask & (1 << 10); // RISCV_HWPROBE_EXT_ZBKX + Features["zknd"] = ExtMask & (1 << 11); // RISCV_HWPROBE_EXT_ZKND + Features["zkne"] = ExtMask & (1 << 12); // RISCV_HWPROBE_EXT_ZKNE + Features["zknh"] = ExtMask & (1 << 13); // RISCV_HWPROBE_EXT_ZKNH + Features["zksed"] = ExtMask & (1 << 14); // RISCV_HWPROBE_EXT_ZKSED + Features["zksh"] = ExtMask & (1 << 15); // RISCV_HWPROBE_EXT_ZKSH + Features["zkt"] = ExtMask & (1 << 16);// RISCV_HWPROBE_EXT_ZKT + Features["zvbb"] = ExtMask & (1 << 17); // RISCV_HWPROBE_EXT_ZVBB + Features["zvbc"] = ExtMask & (1 << 18); // RISCV_HWPROBE_EXT_ZVBC + Features["zvkb"] = ExtMask & (1 << 19); // RISCV_HWPROBE_EXT_ZVKB + Features["zvkg"] = ExtMask & (1 << 20); // RISCV_HWPROBE_EXT_ZVKG + Features["zvkned"] = ExtMask & (1 << 21); // RISCV_HWPROBE_EXT_ZVKNED + Features["zvknha"] = ExtMask & (1 << 22); // RISCV_HWPROBE_EXT_ZVKNHA + Features["zvknhb"] = ExtMask & (1 << 23); // RISCV_HWPROBE_EXT_ZVKNHB + Features["zvksed"] = ExtMask & (1 << 24); // RISCV_HWPROBE_EXT_ZVKSED + Features["zvksh"] = ExtMask & (1 << 25); // RISCV_HWPROBE_EXT_ZVKSH + Features["zvkt"] = ExtMask & (1 << 26); // RISCV_HWPROBE_EXT_ZVKT + Features["zfh"] = ExtMask & (1 << 27);// RISCV_HWPROBE_EXT_ZFH + Features["zfhmin"] = ExtMask & (1 << 28); // RISCV_HWPROBE_EXT_ZFHMIN + Features["zihintntl"] = ExtMask & (1 << 29); // RISCV_HWPROBE_EXT_ZIHINTNTL + Features["zvfh"] = ExtMask & (1 << 30); // RISCV_HWPROBE_EXT_ZVFH + Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN + Features["zfa"] = ExtMask & (1ULL << 32); // RISCV_HWPROBE_EXT_ZFA + // TODO: set ztso when it is no longer experimental. + // Features["ztso"] = ExtMask & (1ULL << 33);// RISCV_HWPROBE_EXT_ZTSO dtcxzyw wrote: Hwprobe docs says the core supports Ztso ***v1.0*** when RISCV_HWPROBE_EXT_ZTSO is set. > RISCV_HWPROBE_EXT_ZTSO: The Ztso extension is supported as defined in the RISC-V ISA manual starting from [commit 5618fb5a216b](https://github.com/riscv/riscv-isa-manual/commit/5618fb5a216b6eb76cbd2b1c8e3d1b55628a072a) (“Ztso is now ratified.”) I don't think it's appropriate to add experimental features for users. https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
@@ -2002,6 +2003,76 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; +bool sys::getHostCPUFeatures(StringMap &Features) { + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0}, + {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query, +/*pair_count=*/std::size(Query), /*cpu_count=*/0, +/*cpus=*/0, /*flags=*/0); + if (Ret != 0) +return false; + + uint64_t BaseMask = Query[0].Value; + // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set. + if (BaseMask & 1) { +Features["i"] = true; +Features["m"] = true; +Features["a"] = true; + } + + uint64_t ExtMask = Query[1].Value; dtcxzyw wrote: FYI, openjdk still uses the value in `RISCV_HWPROBE_KEY_IMA_EXT_0` even if `RISCV_HWPROBE_BASE_BEHAVIOR_IMA` is not set. See https://github.com/openjdk/jdk/blob/e527e1c32fcc7b2560cec540bcde930075ac284a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp#L142-L185. https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
dtcxzyw wrote: Any thoughts? Hopefully I can catch up with the 19 release :) https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
@@ -2002,6 +2003,76 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; +bool sys::getHostCPUFeatures(StringMap &Features) { + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0}, + {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query, dtcxzyw wrote: Currently `sys::getHostCPUFeatures` has three callers: + clang -> `riscv::getRISCVTargetFeatures` + llvm-tools -> `codegen::getFeaturesStr` + JIT users -> `JITTargetMachineBuilder::detectHost` I don't think there are any opportunities to reuse the result. BTW, https://github.com/llvm/llvm-project/pull/85790 may benefit from the vDSO symbol, but it implements caching itself. I didn't use the glibc call `__riscv_hwprobe` since `sys/hwprobe.h` was unavailable on my RV board :( https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
@@ -83,8 +83,14 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, // and other features (ex. mirco architecture feature) from mcpu if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { StringRef CPU = A->getValue(); -if (CPU == "native") +if (CPU == "native") { CPU = llvm::sys::getHostCPUName(); + llvm::StringMap HostFeatures; + if (llvm::sys::getHostCPUFeatures(HostFeatures)) +for (auto &F : HostFeatures) + Features.push_back( + Args.MakeArgString((F.second ? "+" : "-") + F.first())); +} dtcxzyw wrote: @wangpc-pp @topperc Are there any equivalents of the helper `printMArch`? https://github.com/llvm/llvm-project/blob/ba60d8a11af2cdd7e80e2fd968cdf52adcabf5a1/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp#L90-L123 https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Pipelines] Move IPSCCP after inliner pipeline (PR #96620)
dtcxzyw wrote: > This patch causes some significant performance regressions on llvm-test-suite > (rv64gc-O3-thinlto): > > Name Before After Ratio > SingleSource/Benchmarks/Shootout/Shootout-random 2.150161677 > 3.300161641 + 53.5% > SingleSource/Benchmarks/Polybench/linear-algebra/kernels/trisolv/trisolv > 0.111845159 0.145389494 +30.0% > SingleSource/Benchmarks/Adobe-C++/functionobjects 5.489498263 > 6.827863965 +24.4% It has been fixed. But this patch didn't show a positive net effect :( https://github.com/llvm/llvm-project/pull/96620 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Pipelines] Move IPSCCP after inliner pipeline (PR #96620)
dtcxzyw wrote: > Does that mean it has a negative net effect, or its neutral It is neutral. > (in which case the original motivating case should be enough). But this patch may have an impact on compile time. https://github.com/llvm/llvm-project/pull/96620 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/94352 >From ff839bef048a65760f4cd0e9abafe11cfebd9362 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 21:08:27 +0800 Subject: [PATCH 01/12] [RISCV] Add support for getHostCPUFeatures using hwprobe Co-authored-by: Yangyu Chen --- llvm/lib/TargetParser/Host.cpp | 68 ++ 1 file changed, 68 insertions(+) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 68155acd9e5bc..b4a13b38eb380 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1998,6 +1998,74 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +#ifdef __has_include +#if __has_include() +#include +#endif +#endif +bool sys::getHostCPUFeatures(StringMap &Features) { +#ifdef RISCV_HWPROBE_KEY_MVENDORID + riscv_hwprobe Query[2]{ + {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, + {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, + }; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, +/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + if (Ret != 0) +return false; + + uint64_t ExtMask = Query[0].value; + Features["f"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["d"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["c"] = ExtMask & RISCV_HWPROBE_IMA_C; + Features["v"] = ExtMask & RISCV_HWPROBE_IMA_V; + Features["zba"] = ExtMask & RISCV_HWPROBE_IMA_ZBA; + Features["zbb"] = ExtMask & RISCV_HWPROBE_IMA_ZBB; + Features["zbs"] = ExtMask & RISCV_HWPROBE_IMA_ZBS; + Features["zicboz"] = ExtMask & RISCV_HWPROBE_IMA_ZICBOZ; + Features["zbc"] = ExtMask & RISCV_HWPROBE_IMA_ZBC; + Features["zbkb"] = ExtMask & RISCV_HWPROBE_IMA_ZBKB; + Features["zbkc"] = ExtMask & RISCV_HWPROBE_IMA_ZBKC; + Features["zbkx"] = ExtMask & RISCV_HWPROBE_IMA_ZBKX; + Features["zknd"] = ExtMask & RISCV_HWPROBE_IMA_ZKND; + Features["zkne"] = ExtMask & RISCV_HWPROBE_IMA_ZKNE; + Features["zknh"] = ExtMask & RISCV_HWPROBE_IMA_ZKNH; + Features["zksed"] = ExtMask & RISCV_HWPROBE_IMA_ZKSED; + Features["zksh"] = ExtMask & RISCV_HWPROBE_IMA_ZKSH; + Features["zkt"] = ExtMask & RISCV_HWPROBE_IMA_ZKT; + Features["zvbb"] = ExtMask & RISCV_HWPROBE_IMA_ZVBB; + Features["zvbc"] = ExtMask & RISCV_HWPROBE_IMA_ZVBC; + Features["zvkb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKB; + Features["zvkg"] = ExtMask & RISCV_HWPROBE_IMA_ZVKG; + Features["zvkned"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNED; + Features["zvknha"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHA; + Features["zvknhb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHB; + Features["zvksed"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSED; + Features["zvksh"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSH; + Features["zvkt"] = ExtMask & RISCV_HWPROBE_IMA_ZVKT; + Features["zfh"] = ExtMask & RISCV_HWPROBE_IMA_ZFH; + Features["zfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZFHMIN; + Features["zihintntl"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTNTL; + Features["zvfh"] = ExtMask & RISCV_HWPROBE_IMA_ZVFH; + Features["zvfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZVFHMIN; + Features["zfa"] = ExtMask & RISCV_HWPROBE_IMA_ZFA; + Features["ztso"] = ExtMask & RISCV_HWPROBE_IMA_ZTSO; + Features["zacas"] = ExtMask & RISCV_HWPROBE_IMA_ZACAS; + Features["zicond"] = ExtMask & RISCV_HWPROBE_IMA_ZICOND; + Features["zihintpause"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTPAUSE; + + uint64_t MisalignedMask = Query[1].value; + if (MisalignedMask == RISCV_HWPROBE_MISALIGNED_FAST) { +Features["unaligned-scalar-mem"] = true; +Features["unaligned-vector-mem"] = true; + } + + return true; +#else + return false; +#endif +} #else bool sys::getHostCPUFeatures(StringMap &Features) { return false; } #endif >From a2fa6e3d64d3a1e2a8e3a7af91068bdb1fda28b1 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 22:10:55 +0800 Subject: [PATCH 02/12] [RISCV] Address review comments. --- llvm/lib/TargetParser/Host.cpp | 112 +++-- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index b4a13b38eb380..ec275c0a7fded 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1999,72 +1999,64 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } #elif defined(__linux__) && defined(__riscv) -#ifdef __has_include -#if __has_include() -#include -#endif -#endif +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; bool sys::getHostCPUFeatures(StringMap &Features) { -#ifdef RISCV_HWPROBE_KEY_MVENDORID - riscv_hwprobe Query[2]{ - {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, - {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, - }; - int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, -/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + i
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
@@ -83,8 +83,14 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, // and other features (ex. mirco architecture feature) from mcpu if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { StringRef CPU = A->getValue(); -if (CPU == "native") +if (CPU == "native") { CPU = llvm::sys::getHostCPUName(); + llvm::StringMap HostFeatures; + if (llvm::sys::getHostCPUFeatures(HostFeatures)) +for (auto &F : HostFeatures) + Features.push_back( + Args.MakeArgString((F.second ? "+" : "-") + F.first())); +} dtcxzyw wrote: Done. https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
@@ -83,8 +83,14 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, // and other features (ex. mirco architecture feature) from mcpu if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { StringRef CPU = A->getValue(); -if (CPU == "native") +if (CPU == "native") { CPU = llvm::sys::getHostCPUName(); + llvm::StringMap HostFeatures; + if (llvm::sys::getHostCPUFeatures(HostFeatures)) +for (auto &F : HostFeatures) + Features.push_back( + Args.MakeArgString((F.second ? "+" : "-") + F.first())); +} dtcxzyw wrote: See https://github.com/llvm/llvm-project/blob/0f5fa3558eb36823c16ba81a4c6e6e23a5f9df24/clang/lib/Driver/ToolChains/Arch/RISCV.cpp#L72-L78. https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
@@ -290,8 +290,24 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args, // 2. Get march (isa string) based on `-mcpu=` if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { StringRef CPU = A->getValue(); -if (CPU == "native") +if (CPU == "native") { CPU = llvm::sys::getHostCPUName(); + // If the target cpu is unrecognized, use target features. + if (CPU.empty() || CPU.starts_with("generic")) { +llvm::StringMap HostFeatures; +if (llvm::sys::getHostCPUFeatures(HostFeatures)) { + std::vector Features; + for (auto &F : HostFeatures) +Features.push_back( +Args.MakeArgString((F.second ? "+" : "-") + F.first())); + + auto ParseResult = llvm::RISCVISAInfo::parseFeatures( + Triple.isRISCV32() ? 32 : 64, Features); + if (ParseResult) +return (*ParseResult)->toString(); dtcxzyw wrote: Sorry, I forget that `riscv::getRISCVArch` returns `StringRef`. https://github.com/llvm/llvm-project/pull/94352 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/94352 >From ff839bef048a65760f4cd0e9abafe11cfebd9362 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 21:08:27 +0800 Subject: [PATCH 01/13] [RISCV] Add support for getHostCPUFeatures using hwprobe Co-authored-by: Yangyu Chen --- llvm/lib/TargetParser/Host.cpp | 68 ++ 1 file changed, 68 insertions(+) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 68155acd9e5bc..b4a13b38eb380 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1998,6 +1998,74 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +#ifdef __has_include +#if __has_include() +#include +#endif +#endif +bool sys::getHostCPUFeatures(StringMap &Features) { +#ifdef RISCV_HWPROBE_KEY_MVENDORID + riscv_hwprobe Query[2]{ + {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, + {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, + }; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, +/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + if (Ret != 0) +return false; + + uint64_t ExtMask = Query[0].value; + Features["f"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["d"] = ExtMask & RISCV_HWPROBE_IMA_FD; + Features["c"] = ExtMask & RISCV_HWPROBE_IMA_C; + Features["v"] = ExtMask & RISCV_HWPROBE_IMA_V; + Features["zba"] = ExtMask & RISCV_HWPROBE_IMA_ZBA; + Features["zbb"] = ExtMask & RISCV_HWPROBE_IMA_ZBB; + Features["zbs"] = ExtMask & RISCV_HWPROBE_IMA_ZBS; + Features["zicboz"] = ExtMask & RISCV_HWPROBE_IMA_ZICBOZ; + Features["zbc"] = ExtMask & RISCV_HWPROBE_IMA_ZBC; + Features["zbkb"] = ExtMask & RISCV_HWPROBE_IMA_ZBKB; + Features["zbkc"] = ExtMask & RISCV_HWPROBE_IMA_ZBKC; + Features["zbkx"] = ExtMask & RISCV_HWPROBE_IMA_ZBKX; + Features["zknd"] = ExtMask & RISCV_HWPROBE_IMA_ZKND; + Features["zkne"] = ExtMask & RISCV_HWPROBE_IMA_ZKNE; + Features["zknh"] = ExtMask & RISCV_HWPROBE_IMA_ZKNH; + Features["zksed"] = ExtMask & RISCV_HWPROBE_IMA_ZKSED; + Features["zksh"] = ExtMask & RISCV_HWPROBE_IMA_ZKSH; + Features["zkt"] = ExtMask & RISCV_HWPROBE_IMA_ZKT; + Features["zvbb"] = ExtMask & RISCV_HWPROBE_IMA_ZVBB; + Features["zvbc"] = ExtMask & RISCV_HWPROBE_IMA_ZVBC; + Features["zvkb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKB; + Features["zvkg"] = ExtMask & RISCV_HWPROBE_IMA_ZVKG; + Features["zvkned"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNED; + Features["zvknha"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHA; + Features["zvknhb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHB; + Features["zvksed"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSED; + Features["zvksh"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSH; + Features["zvkt"] = ExtMask & RISCV_HWPROBE_IMA_ZVKT; + Features["zfh"] = ExtMask & RISCV_HWPROBE_IMA_ZFH; + Features["zfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZFHMIN; + Features["zihintntl"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTNTL; + Features["zvfh"] = ExtMask & RISCV_HWPROBE_IMA_ZVFH; + Features["zvfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZVFHMIN; + Features["zfa"] = ExtMask & RISCV_HWPROBE_IMA_ZFA; + Features["ztso"] = ExtMask & RISCV_HWPROBE_IMA_ZTSO; + Features["zacas"] = ExtMask & RISCV_HWPROBE_IMA_ZACAS; + Features["zicond"] = ExtMask & RISCV_HWPROBE_IMA_ZICOND; + Features["zihintpause"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTPAUSE; + + uint64_t MisalignedMask = Query[1].value; + if (MisalignedMask == RISCV_HWPROBE_MISALIGNED_FAST) { +Features["unaligned-scalar-mem"] = true; +Features["unaligned-vector-mem"] = true; + } + + return true; +#else + return false; +#endif +} #else bool sys::getHostCPUFeatures(StringMap &Features) { return false; } #endif >From a2fa6e3d64d3a1e2a8e3a7af91068bdb1fda28b1 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 4 Jun 2024 22:10:55 +0800 Subject: [PATCH 02/13] [RISCV] Address review comments. --- llvm/lib/TargetParser/Host.cpp | 112 +++-- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index b4a13b38eb380..ec275c0a7fded 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1999,72 +1999,64 @@ bool sys::getHostCPUFeatures(StringMap &Features) { return true; } #elif defined(__linux__) && defined(__riscv) -#ifdef __has_include -#if __has_include() -#include -#endif -#endif +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; bool sys::getHostCPUFeatures(StringMap &Features) { -#ifdef RISCV_HWPROBE_KEY_MVENDORID - riscv_hwprobe Query[2]{ - {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, - {RISCV_HWPROBE_KEY_CPUPERF_0, 0}, - }; - int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query, -/*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0); + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + i
[clang] [InstCombine] Add combines/simplifications for `llvm.ptrmask` (PR #67166)
@@ -1964,18 +1964,78 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { break; } case Intrinsic::ptrmask: { +KnownBits Known(DL.getPointerTypeSizeInBits(II->getType())); +if (SimplifyDemandedInstructionBits(*II, Known)) + return II; + +Value *Op0 = II->getArgOperand(0); +Value *Op1 = II->getArgOperand(1); +// Fail loudly in case this is ever changed. +// TODO: If vector types are supported the merging of (ptrmask (ptrmask)) +// need to ensure we don't merge a vectype with non-vec type. +assert(!Op0->getType()->isVectorTy() && !Op1->getType()->isVectorTy() && + "These combines where written at a time when ptrmask did not " + "support vector types and may not work for vectors"); + Value *InnerPtr, *InnerMask; -if (match(II->getArgOperand(0), - m_OneUse(m_Intrinsic(m_Value(InnerPtr), - m_Value(InnerMask) { - if (II->getArgOperand(1)->getType() == InnerMask->getType()) { -Value *NewMask = Builder.CreateAnd(II->getArgOperand(1), InnerMask); -return replaceInstUsesWith( -*II, -Builder.CreateIntrinsic(InnerPtr->getType(), Intrinsic::ptrmask, -{InnerPtr, NewMask})); +bool Changed = false; +// Combine: +// (ptrmask (ptrmask p, A), B) +//-> (ptrmask p, (and A, B)) +if (match(Op0, m_OneUse(m_Intrinsic( + m_Value(InnerPtr), m_Value(InnerMask) { + // See if combining the two masks is free. + bool OkayToMerge = InnerMask->getType() == Op1->getType(); + bool NeedsNew = false; + if (!OkayToMerge) { +if (match(InnerMask, m_ImmConstant())) { + InnerMask = Builder.CreateZExtOrTrunc(InnerMask, Op1->getType()); + OkayToMerge = true; +} else if (match(Op1, m_ImmConstant())) { + Op1 = Builder.CreateZExtOrTrunc(Op1, InnerMask->getType()); + OkayToMerge = true; + // Need to create a new one here, as the intrinsic id needs to change. + NeedsNew = true; +} + } + if (InnerMask->getType() == Op1->getType()) { dtcxzyw wrote: `OkayToMerge` is unused? https://github.com/llvm/llvm-project/pull/67166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65910 >From 9bb817aa40dd9bc1bbb18b4cf4bc079145c8ecaa Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 03:58:02 +0800 Subject: [PATCH 1/2] [ValueTracking] Simplify uaddo pattern --- llvm/lib/Analysis/ValueTracking.cpp | 23 .../InstSimplify/and-or-implied-cond.ll | 104 ++ 2 files changed, 127 insertions(+) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index c4153b824c37e0a..5aaff4ee81be969 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8291,6 +8291,29 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC))) return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC); + // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 From 83fa03f89c69a0a13336f6761023bb1415f92505 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sun, 24 Sep 2023 17:04:32 +0800 Subject: [PATCH 2/2] fixup! [ValueTracking] Simplify uaddo pattern --- llvm/lib/Analysis/ValueTracking.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 5aaff4ee81be969..f2278f3b7097dac 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8308,7 +8308,7 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, RPred = ICmpInst::getSwappedPredicate(RPred); } if (L0 == R0 && -(LPred == ICmpInst::ICMP_UGE || LPred == ICmpInst::ICMP_ULT) && +(LPred == ICmpInst::ICMP_ULT || LPred == ICmpInst::ICMP_UGE) && (RPred == ICmpInst::ICMP_ULT || RPred == ICmpInst::ICMP_UGE) && match(L0, m_c_Add(m_Specific(L1), m_Specific(R1 return LPred == RPred; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65910 >From 9bb817aa40dd9bc1bbb18b4cf4bc079145c8ecaa Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 03:58:02 +0800 Subject: [PATCH 1/2] [ValueTracking] Simplify uaddo pattern --- llvm/lib/Analysis/ValueTracking.cpp | 23 .../InstSimplify/and-or-implied-cond.ll | 104 ++ 2 files changed, 127 insertions(+) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index c4153b824c37e0a..5aaff4ee81be969 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8291,6 +8291,29 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC))) return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC); + // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 From 83fa03f89c69a0a13336f6761023bb1415f92505 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sun, 24 Sep 2023 17:04:32 +0800 Subject: [PATCH 2/2] fixup! [ValueTracking] Simplify uaddo pattern --- llvm/lib/Analysis/ValueTracking.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 5aaff4ee81be969..f2278f3b7097dac 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8308,7 +8308,7 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, RPred = ICmpInst::getSwappedPredicate(RPred); } if (L0 == R0 && -(LPred == ICmpInst::ICMP_UGE || LPred == ICmpInst::ICMP_ULT) && +(LPred == ICmpInst::ICMP_ULT || LPred == ICmpInst::ICMP_UGE) && (RPred == ICmpInst::ICMP_ULT || RPred == ICmpInst::ICMP_UGE) && match(L0, m_c_Add(m_Specific(L1), m_Specific(R1 return LPred == RPred; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [ValueTracking] Simplify uaddo pattern (PR #65910)
@@ -8291,6 +8291,29 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC))) return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC); + // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 u L1 -> R0 >u R1` and `L0 <=u L1 -> R0 <=u R1`. Alive2: https://alive2.llvm.org/ce/z/VKtFkD https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ValueTracking] Simplify uaddo pattern (PR #65910)
@@ -8291,6 +8291,29 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC))) return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC); + // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 u L1 -> R0 >u R1` and `L0 <=u L1 -> R0 <=u R1`. Alive2: https://alive2.llvm.org/ce/z/VKtFkD https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65852 >From d9d8bcbb98e8f5aecb9733329389d61a489bd731 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 23:07:29 +0800 Subject: [PATCH 1/7] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` --- .../InstCombine/InstCombineCompares.cpp | 62 ++ .../test/Transforms/InstCombine/icmp-range.ll | 181 ++ 2 files changed, 243 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 9fdc46fec631679..837b8e6d2619989 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6309,7 +6309,69 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); + ICmpInst::Predicate Pred1, Pred2; const APInt *C; + // icmp eq/ne X, (zext (icmp eq/ne X, C)) + if (match(&I, m_c_ICmp(Pred1, m_Value(X), + m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) && + ICmpInst::isEquality(Pred1) && ICmpInst::isEquality(Pred2)) { +if (C->isZero()) { + if (Pred2 == ICmpInst::ICMP_EQ) { +// icmp eq X, (zext (icmp eq X, 0)) --> false +// icmp ne X, (zext (icmp eq X, 0)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp ne X, 0)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp ne X, 0)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else if (C->isOne()) { + if (Pred2 == ICmpInst::ICMP_NE) { +// icmp eq X, (zext (icmp ne X, 1)) --> false +// icmp ne X, (zext (icmp ne X, 1)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp eq X, 1)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp eq X, 1)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else { + // C != 0 && C != 1 + // icmp eq X, (zext (icmp eq X, C)) --> icmp eq X, 0 + // icmp eq X, (zext (icmp ne X, C)) --> icmp eq X, 1 + // icmp ne X, (zext (icmp eq X, C)) --> icmp ne X, 0 + // icmp ne X, (zext (icmp ne X, C)) --> icmp ne X, 1 + return ICmpInst::Create( + Instruction::ICmp, Pred1, X, + Constant::getIntegerValue( + X->getType(), + APInt(X->getType()->getScalarSizeInBits(), +static_cast(Pred2 == ICmpInst::ICMP_NE; +} + } + if (match(I.getOperand(0), m_c_Add(m_ZExt(m_Value(X)), m_SExt(m_Value(Y && match(I.getOperand(1), m_APInt(C)) && X->getType()->isIntOrIntVectorTy(1) && diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll index 4281e09cb0309c8..15424fce33fdeea 100644 --- a/llvm/test/Transforms/InstCombine/icmp-range.ll +++ b/llvm/test/Transforms/InstCombine/icmp-range.ll @@ -1034,6 +1034,187 @@ define i1 @icmp_ne_bool_1(ptr %ptr) { ret i1 %cmp } +define i1 @icmp_ne_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_eq_zero( +; CHECK-NEXT:ret i1 true +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_ne_zext_ne_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_ne_zero( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 +; CHECK-NEXT:ret i1 [[CMP1]] +; + %cmp = icmp ne i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_eq_zext_eq_zero( +; CHECK-NEXT:ret i1 false +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp eq i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_ne_zero(i32 %
[clang] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65852 >From d9d8bcbb98e8f5aecb9733329389d61a489bd731 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 23:07:29 +0800 Subject: [PATCH 1/7] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` --- .../InstCombine/InstCombineCompares.cpp | 62 ++ .../test/Transforms/InstCombine/icmp-range.ll | 181 ++ 2 files changed, 243 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 9fdc46fec631679..837b8e6d2619989 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6309,7 +6309,69 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); + ICmpInst::Predicate Pred1, Pred2; const APInt *C; + // icmp eq/ne X, (zext (icmp eq/ne X, C)) + if (match(&I, m_c_ICmp(Pred1, m_Value(X), + m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) && + ICmpInst::isEquality(Pred1) && ICmpInst::isEquality(Pred2)) { +if (C->isZero()) { + if (Pred2 == ICmpInst::ICMP_EQ) { +// icmp eq X, (zext (icmp eq X, 0)) --> false +// icmp ne X, (zext (icmp eq X, 0)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp ne X, 0)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp ne X, 0)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else if (C->isOne()) { + if (Pred2 == ICmpInst::ICMP_NE) { +// icmp eq X, (zext (icmp ne X, 1)) --> false +// icmp ne X, (zext (icmp ne X, 1)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp eq X, 1)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp eq X, 1)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else { + // C != 0 && C != 1 + // icmp eq X, (zext (icmp eq X, C)) --> icmp eq X, 0 + // icmp eq X, (zext (icmp ne X, C)) --> icmp eq X, 1 + // icmp ne X, (zext (icmp eq X, C)) --> icmp ne X, 0 + // icmp ne X, (zext (icmp ne X, C)) --> icmp ne X, 1 + return ICmpInst::Create( + Instruction::ICmp, Pred1, X, + Constant::getIntegerValue( + X->getType(), + APInt(X->getType()->getScalarSizeInBits(), +static_cast(Pred2 == ICmpInst::ICMP_NE; +} + } + if (match(I.getOperand(0), m_c_Add(m_ZExt(m_Value(X)), m_SExt(m_Value(Y && match(I.getOperand(1), m_APInt(C)) && X->getType()->isIntOrIntVectorTy(1) && diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll index 4281e09cb0309c8..15424fce33fdeea 100644 --- a/llvm/test/Transforms/InstCombine/icmp-range.ll +++ b/llvm/test/Transforms/InstCombine/icmp-range.ll @@ -1034,6 +1034,187 @@ define i1 @icmp_ne_bool_1(ptr %ptr) { ret i1 %cmp } +define i1 @icmp_ne_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_eq_zero( +; CHECK-NEXT:ret i1 true +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_ne_zext_ne_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_ne_zero( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 +; CHECK-NEXT:ret i1 [[CMP1]] +; + %cmp = icmp ne i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_eq_zext_eq_zero( +; CHECK-NEXT:ret i1 false +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp eq i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_ne_zero(i32 %
[clang] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ValueTracking] Simplify uaddo pattern (PR #65910)
@@ -8291,6 +8291,29 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC))) return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC); + // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 https://alive2.llvm.org/ce/z/eWsJH2. https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw unresolved https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65852 >From d9d8bcbb98e8f5aecb9733329389d61a489bd731 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 23:07:29 +0800 Subject: [PATCH 1/8] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` --- .../InstCombine/InstCombineCompares.cpp | 62 ++ .../test/Transforms/InstCombine/icmp-range.ll | 181 ++ 2 files changed, 243 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 9fdc46fec631679..837b8e6d2619989 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6309,7 +6309,69 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); + ICmpInst::Predicate Pred1, Pred2; const APInt *C; + // icmp eq/ne X, (zext (icmp eq/ne X, C)) + if (match(&I, m_c_ICmp(Pred1, m_Value(X), + m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) && + ICmpInst::isEquality(Pred1) && ICmpInst::isEquality(Pred2)) { +if (C->isZero()) { + if (Pred2 == ICmpInst::ICMP_EQ) { +// icmp eq X, (zext (icmp eq X, 0)) --> false +// icmp ne X, (zext (icmp eq X, 0)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp ne X, 0)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp ne X, 0)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else if (C->isOne()) { + if (Pred2 == ICmpInst::ICMP_NE) { +// icmp eq X, (zext (icmp ne X, 1)) --> false +// icmp ne X, (zext (icmp ne X, 1)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp eq X, 1)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp eq X, 1)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else { + // C != 0 && C != 1 + // icmp eq X, (zext (icmp eq X, C)) --> icmp eq X, 0 + // icmp eq X, (zext (icmp ne X, C)) --> icmp eq X, 1 + // icmp ne X, (zext (icmp eq X, C)) --> icmp ne X, 0 + // icmp ne X, (zext (icmp ne X, C)) --> icmp ne X, 1 + return ICmpInst::Create( + Instruction::ICmp, Pred1, X, + Constant::getIntegerValue( + X->getType(), + APInt(X->getType()->getScalarSizeInBits(), +static_cast(Pred2 == ICmpInst::ICMP_NE; +} + } + if (match(I.getOperand(0), m_c_Add(m_ZExt(m_Value(X)), m_SExt(m_Value(Y && match(I.getOperand(1), m_APInt(C)) && X->getType()->isIntOrIntVectorTy(1) && diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll index 4281e09cb0309c8..15424fce33fdeea 100644 --- a/llvm/test/Transforms/InstCombine/icmp-range.ll +++ b/llvm/test/Transforms/InstCombine/icmp-range.ll @@ -1034,6 +1034,187 @@ define i1 @icmp_ne_bool_1(ptr %ptr) { ret i1 %cmp } +define i1 @icmp_ne_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_eq_zero( +; CHECK-NEXT:ret i1 true +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_ne_zext_ne_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_ne_zero( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 +; CHECK-NEXT:ret i1 [[CMP1]] +; + %cmp = icmp ne i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_eq_zext_eq_zero( +; CHECK-NEXT:ret i1 false +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp eq i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_ne_zero(i32 %
[clang-tools-extra] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65852 >From d9d8bcbb98e8f5aecb9733329389d61a489bd731 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 23:07:29 +0800 Subject: [PATCH 1/8] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` --- .../InstCombine/InstCombineCompares.cpp | 62 ++ .../test/Transforms/InstCombine/icmp-range.ll | 181 ++ 2 files changed, 243 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 9fdc46fec631679..837b8e6d2619989 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6309,7 +6309,69 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); + ICmpInst::Predicate Pred1, Pred2; const APInt *C; + // icmp eq/ne X, (zext (icmp eq/ne X, C)) + if (match(&I, m_c_ICmp(Pred1, m_Value(X), + m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) && + ICmpInst::isEquality(Pred1) && ICmpInst::isEquality(Pred2)) { +if (C->isZero()) { + if (Pred2 == ICmpInst::ICMP_EQ) { +// icmp eq X, (zext (icmp eq X, 0)) --> false +// icmp ne X, (zext (icmp eq X, 0)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp ne X, 0)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp ne X, 0)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else if (C->isOne()) { + if (Pred2 == ICmpInst::ICMP_NE) { +// icmp eq X, (zext (icmp ne X, 1)) --> false +// icmp ne X, (zext (icmp ne X, 1)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp eq X, 1)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp eq X, 1)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else { + // C != 0 && C != 1 + // icmp eq X, (zext (icmp eq X, C)) --> icmp eq X, 0 + // icmp eq X, (zext (icmp ne X, C)) --> icmp eq X, 1 + // icmp ne X, (zext (icmp eq X, C)) --> icmp ne X, 0 + // icmp ne X, (zext (icmp ne X, C)) --> icmp ne X, 1 + return ICmpInst::Create( + Instruction::ICmp, Pred1, X, + Constant::getIntegerValue( + X->getType(), + APInt(X->getType()->getScalarSizeInBits(), +static_cast(Pred2 == ICmpInst::ICMP_NE; +} + } + if (match(I.getOperand(0), m_c_Add(m_ZExt(m_Value(X)), m_SExt(m_Value(Y && match(I.getOperand(1), m_APInt(C)) && X->getType()->isIntOrIntVectorTy(1) && diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll index 4281e09cb0309c8..15424fce33fdeea 100644 --- a/llvm/test/Transforms/InstCombine/icmp-range.ll +++ b/llvm/test/Transforms/InstCombine/icmp-range.ll @@ -1034,6 +1034,187 @@ define i1 @icmp_ne_bool_1(ptr %ptr) { ret i1 %cmp } +define i1 @icmp_ne_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_eq_zero( +; CHECK-NEXT:ret i1 true +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_ne_zext_ne_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_ne_zero( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 +; CHECK-NEXT:ret i1 [[CMP1]] +; + %cmp = icmp ne i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_eq_zext_eq_zero( +; CHECK-NEXT:ret i1 false +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp eq i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_ne_zero(i32 %
[clang] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65934 >From 2fe5756dd4d49580d3a23b0ff1b72535f725915e Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 15:51:46 +0800 Subject: [PATCH 1/4] [RISCV] Eliminate dead li after emitting VSETVLIs --- llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 22 ++--- .../RISCV/rvv/fixed-vectors-masked-gather.ll | 24 --- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp index b42ad269c18de6f..918c96beb29afca 100644 --- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp +++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp @@ -757,7 +757,8 @@ class RISCVInsertVSETVLI : public MachineFunctionPass { bool computeVLVTYPEChanges(const MachineBasicBlock &MBB, VSETVLIInfo &Info) const; void computeIncomingVLVTYPE(const MachineBasicBlock &MBB); - void emitVSETVLIs(MachineBasicBlock &MBB); + void emitVSETVLIs(MachineBasicBlock &MBB, +SmallVectorImpl &DeadVLInstrs); void doLocalPostpass(MachineBasicBlock &MBB); void doPRE(MachineBasicBlock &MBB); void insertReadVL(MachineBasicBlock &MBB); @@ -1216,7 +1217,8 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require, return false; } -void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { +void RISCVInsertVSETVLI::emitVSETVLIs( +MachineBasicBlock &MBB, SmallVectorImpl &DeadVLInstrs) { VSETVLIInfo CurInfo = BlockInfo[MBB.getNumber()].Pred; // Track whether the prefix of the block we've scanned is transparent // (meaning has not yet changed the abstract state). @@ -1255,6 +1257,13 @@ void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI)); if (VLOp.isReg()) { // Erase the AVL operand from the instruction. + if (MachineInstr *MI = MRI->getVRegDef(VLOp.getReg()); + MI && MI->getOpcode() == RISCV::ADDI && + MI->getOperand(1).isReg() && MI->getOperand(2).isImm() && + MI->getOperand(1).getReg() == RISCV::X0 && + MI->getOperand(2).getImm() != 0) +DeadVLInstrs.push_back(MI); + VLOp.setReg(RISCV::NoRegister); VLOp.setIsKill(false); } @@ -1580,8 +1589,9 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { // Phase 2 information to avoid adding vsetvlis before the first vector // instruction in the block if the VL/VTYPE is satisfied by its // predecessors. + SmallVector DeadVLInstrs; for (MachineBasicBlock &MBB : MF) -emitVSETVLIs(MBB); +emitVSETVLIs(MBB, DeadVLInstrs); // Now that all vsetvlis are explicit, go through and do block local // DSE and peephole based demanded fields based transforms. Note that @@ -1592,6 +1602,12 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { for (MachineBasicBlock &MBB : MF) doLocalPostpass(MBB); + // Remove dead LI instructions that set VL. + for (MachineInstr *MI : DeadVLInstrs) { +if (MRI->use_nodbg_empty(MI->getOperand(0).getReg())) + MI->eraseFromParent(); + } + // Once we're fully done rewriting all the instructions, do a final pass // through to check for VSETVLIs which write to an unused destination. // For the non X0, X0 variant, we can replace the destination register diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll index f7352b4659e5a9b..0d306775528ed86 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll @@ -12393,7 +12393,6 @@ define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m ; RV64ZVE32F-NEXT:vmv.x.s a2, v12 ; RV64ZVE32F-NEXT:add a2, a0, a2 ; RV64ZVE32F-NEXT:lbu a2, 0(a2) -; RV64ZVE32F-NEXT:li a3, 32 ; RV64ZVE32F-NEXT:vmv.s.x v12, a2 ; RV64ZVE32F-NEXT:vsetivli zero, 2, e8, m2, tu, ma ; RV64ZVE32F-NEXT:vslideup.vi v10, v12, 1 @@ -12431,7 +12430,6 @@ define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m ; RV64ZVE32F-NEXT:vmv.x.s a2, v14 ; RV64ZVE32F-NEXT:add a2, a0, a2 ; RV64ZVE32F-NEXT:lbu a2, 0(a2) -; RV64ZVE32F-NEXT:li a3, 32 ; RV64ZVE32F-NEXT:vmv.s.x v14, a2 ; RV64ZVE32F-NEXT:vsetivli zero, 6, e8, m2, tu, ma ; RV64ZVE32F-NEXT:vslideup.vi v10, v14, 5 @@ -12455,7 +12453,6 @@ define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m ; RV64ZVE32F-NEXT:vmv.x.s a2, v13 ; RV64ZVE32F-NEXT:add a2, a0, a2 ; RV64ZVE32F-NEXT:lbu a2, 0(a2) -; RV64ZVE32F-NEXT:li a3, 32 ; RV64ZVE32F-NEXT:vmv.s.x v14, a2 ; RV64ZVE32F-NEXT:vsetivli zero, 10, e8, m2, tu, ma ; RV64ZVE32F-NEXT:vslideup.vi v10, v
[clang] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65934 >From 2fe5756dd4d49580d3a23b0ff1b72535f725915e Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 15:51:46 +0800 Subject: [PATCH 1/4] [RISCV] Eliminate dead li after emitting VSETVLIs --- llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 22 ++--- .../RISCV/rvv/fixed-vectors-masked-gather.ll | 24 --- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp index b42ad269c18de6f..918c96beb29afca 100644 --- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp +++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp @@ -757,7 +757,8 @@ class RISCVInsertVSETVLI : public MachineFunctionPass { bool computeVLVTYPEChanges(const MachineBasicBlock &MBB, VSETVLIInfo &Info) const; void computeIncomingVLVTYPE(const MachineBasicBlock &MBB); - void emitVSETVLIs(MachineBasicBlock &MBB); + void emitVSETVLIs(MachineBasicBlock &MBB, +SmallVectorImpl &DeadVLInstrs); void doLocalPostpass(MachineBasicBlock &MBB); void doPRE(MachineBasicBlock &MBB); void insertReadVL(MachineBasicBlock &MBB); @@ -1216,7 +1217,8 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require, return false; } -void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { +void RISCVInsertVSETVLI::emitVSETVLIs( +MachineBasicBlock &MBB, SmallVectorImpl &DeadVLInstrs) { VSETVLIInfo CurInfo = BlockInfo[MBB.getNumber()].Pred; // Track whether the prefix of the block we've scanned is transparent // (meaning has not yet changed the abstract state). @@ -1255,6 +1257,13 @@ void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI)); if (VLOp.isReg()) { // Erase the AVL operand from the instruction. + if (MachineInstr *MI = MRI->getVRegDef(VLOp.getReg()); + MI && MI->getOpcode() == RISCV::ADDI && + MI->getOperand(1).isReg() && MI->getOperand(2).isImm() && + MI->getOperand(1).getReg() == RISCV::X0 && + MI->getOperand(2).getImm() != 0) +DeadVLInstrs.push_back(MI); + VLOp.setReg(RISCV::NoRegister); VLOp.setIsKill(false); } @@ -1580,8 +1589,9 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { // Phase 2 information to avoid adding vsetvlis before the first vector // instruction in the block if the VL/VTYPE is satisfied by its // predecessors. + SmallVector DeadVLInstrs; for (MachineBasicBlock &MBB : MF) -emitVSETVLIs(MBB); +emitVSETVLIs(MBB, DeadVLInstrs); // Now that all vsetvlis are explicit, go through and do block local // DSE and peephole based demanded fields based transforms. Note that @@ -1592,6 +1602,12 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { for (MachineBasicBlock &MBB : MF) doLocalPostpass(MBB); + // Remove dead LI instructions that set VL. + for (MachineInstr *MI : DeadVLInstrs) { +if (MRI->use_nodbg_empty(MI->getOperand(0).getReg())) + MI->eraseFromParent(); + } + // Once we're fully done rewriting all the instructions, do a final pass // through to check for VSETVLIs which write to an unused destination. // For the non X0, X0 variant, we can replace the destination register diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll index f7352b4659e5a9b..0d306775528ed86 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll @@ -12393,7 +12393,6 @@ define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m ; RV64ZVE32F-NEXT:vmv.x.s a2, v12 ; RV64ZVE32F-NEXT:add a2, a0, a2 ; RV64ZVE32F-NEXT:lbu a2, 0(a2) -; RV64ZVE32F-NEXT:li a3, 32 ; RV64ZVE32F-NEXT:vmv.s.x v12, a2 ; RV64ZVE32F-NEXT:vsetivli zero, 2, e8, m2, tu, ma ; RV64ZVE32F-NEXT:vslideup.vi v10, v12, 1 @@ -12431,7 +12430,6 @@ define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m ; RV64ZVE32F-NEXT:vmv.x.s a2, v14 ; RV64ZVE32F-NEXT:add a2, a0, a2 ; RV64ZVE32F-NEXT:lbu a2, 0(a2) -; RV64ZVE32F-NEXT:li a3, 32 ; RV64ZVE32F-NEXT:vmv.s.x v14, a2 ; RV64ZVE32F-NEXT:vsetivli zero, 6, e8, m2, tu, ma ; RV64ZVE32F-NEXT:vslideup.vi v10, v14, 5 @@ -12455,7 +12453,6 @@ define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m ; RV64ZVE32F-NEXT:vmv.x.s a2, v13 ; RV64ZVE32F-NEXT:add a2, a0, a2 ; RV64ZVE32F-NEXT:lbu a2, 0(a2) -; RV64ZVE32F-NEXT:li a3, 32 ; RV64ZVE32F-NEXT:vmv.s.x v14, a2 ; RV64ZVE32F-NEXT:vsetivli zero, 10, e8, m2, tu, ma ; RV64ZVE32F-NEXT:vslideup.vi v10, v
[clang-tools-extra] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
@@ -757,7 +757,8 @@ class RISCVInsertVSETVLI : public MachineFunctionPass { bool computeVLVTYPEChanges(const MachineBasicBlock &MBB, VSETVLIInfo &Info) const; void computeIncomingVLVTYPE(const MachineBasicBlock &MBB); - void emitVSETVLIs(MachineBasicBlock &MBB); + void emitVSETVLIs(MachineBasicBlock &MBB, +SmallVectorImpl &PossiblyDeadVLInstrs); dtcxzyw wrote: I don't think it is a typo. https://github.com/llvm/llvm-project/pull/65934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
@@ -757,7 +757,8 @@ class RISCVInsertVSETVLI : public MachineFunctionPass { bool computeVLVTYPEChanges(const MachineBasicBlock &MBB, VSETVLIInfo &Info) const; void computeIncomingVLVTYPE(const MachineBasicBlock &MBB); - void emitVSETVLIs(MachineBasicBlock &MBB); + void emitVSETVLIs(MachineBasicBlock &MBB, +SmallVectorImpl &PossiblyDeadVLInstrs); dtcxzyw wrote: I don't think it is a typo. https://github.com/llvm/llvm-project/pull/65934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Add combines/simplifications for `llvm.ptrmask` (PR #67166)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/67166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Add combines/simplifications for `llvm.ptrmask` (PR #67166)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/67166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Canonicalize `and(zext(A), B)` into `select A, B & 1, 0` (PR #66740)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/66740 >From 85f7911dfe0f1e9112881a9f503bcd68edfde580 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 19 Sep 2023 10:19:46 +0800 Subject: [PATCH 1/3] [InstCombine] Canonicalize `and(zext(A), B)` into `select A, B & 1, 0` --- .../InstCombine/InstCombineAndOrXor.cpp | 6 .../Transforms/InstCombine/and-or-icmps.ll| 12 +++ llvm/test/Transforms/InstCombine/icmp.ll | 31 ++- llvm/test/Transforms/InstCombine/narrow.ll| 3 +- .../Transforms/InstCombine/zext-or-icmp.ll| 10 +++--- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index ca7dfa82ab5a5d7..7fa432e1fdc1790 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2654,6 +2654,12 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) { A->getType()->isIntOrIntVectorTy(1)) return SelectInst::Create(A, Constant::getNullValue(Ty), B); + // and(zext(A), B) -> A ? (B & 1) : 0 + if (match(&I, m_c_And(m_OneUse(m_ZExt(m_Value(A))), m_Value(B))) && + A->getType()->isIntOrIntVectorTy(1)) +return SelectInst::Create(A, Builder.CreateAnd(B, ConstantInt::get(Ty, 1)), + Constant::getNullValue(Ty)); + // (iN X s>> (N-1)) & Y --> (X s< 0) ? Y : 0 -- with optional sext if (match(&I, m_c_And(m_OneUse(m_SExtOrSelf( m_AShr(m_Value(X), m_APIntAllowUndef(C, diff --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll index 065dbf261e131bf..881a9b7ff129dbb 100644 --- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll +++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll @@ -2769,9 +2769,9 @@ define i64 @icmp_slt_0_and_icmp_sgt_neg1_i64(i64 %x) { define i64 @icmp_slt_0_and_icmp_sge_neg1_i64_fail(i64 %x) { ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i64_fail( ; CHECK-NEXT:[[A:%.*]] = icmp sgt i64 [[X:%.*]], -2 -; CHECK-NEXT:[[B:%.*]] = zext i1 [[A]] to i64 ; CHECK-NEXT:[[C:%.*]] = lshr i64 [[X]], 62 -; CHECK-NEXT:[[D:%.*]] = and i64 [[C]], [[B]] +; CHECK-NEXT:[[TMP1:%.*]] = and i64 [[C]], 1 +; CHECK-NEXT:[[D:%.*]] = select i1 [[A]], i64 [[TMP1]], i64 0 ; CHECK-NEXT:ret i64 [[D]] ; %A = icmp sge i64 %x, -1 @@ -2871,9 +2871,8 @@ define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse1(i32 %x) { define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse2(i32 %x) { ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse2( ; CHECK-NEXT:[[A:%.*]] = icmp sgt i32 [[X:%.*]], -3 -; CHECK-NEXT:[[B:%.*]] = zext i1 [[A]] to i32 ; CHECK-NEXT:[[C:%.*]] = lshr i32 [[X]], 31 -; CHECK-NEXT:[[D:%.*]] = and i32 [[C]], [[B]] +; CHECK-NEXT:[[D:%.*]] = select i1 [[A]], i32 [[C]], i32 0 ; CHECK-NEXT:call void @use32(i32 [[C]]) ; CHECK-NEXT:ret i32 [[D]] ; @@ -2923,10 +2922,9 @@ define i32 @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail1(i32 %x) { define i32 @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_multiuse_fail2(i32 %x, i32 %y) { ; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_multiuse_fail2( -; CHECK-NEXT:[[A:%.*]] = icmp ne i32 [[X:%.*]], -2 -; CHECK-NEXT:[[B:%.*]] = zext i1 [[A]] to i32 +; CHECK-NEXT:[[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], -2 ; CHECK-NEXT:[[C:%.*]] = lshr i32 [[Y:%.*]], 31 -; CHECK-NEXT:[[D:%.*]] = and i32 [[C]], [[B]] +; CHECK-NEXT:[[D:%.*]] = select i1 [[A_NOT]], i32 0, i32 [[C]] ; CHECK-NEXT:call void @use32(i32 [[C]]) ; CHECK-NEXT:ret i32 [[D]] ; diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 666d85d6cc32103..a5c05278f4232e8 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -4441,9 +4441,9 @@ define i1 @redundant_sign_bit_count_ugt_31_30(i32 %x) { define i1 @zext_bool_and_eq0(i1 %x, i8 %y) { ; CHECK-LABEL: @zext_bool_and_eq0( ; CHECK-NEXT:[[TMP1:%.*]] = and i8 [[Y:%.*]], 1 -; CHECK-NEXT:[[TMP2:%.*]] = icmp ne i8 [[TMP1]], 0 -; CHECK-NEXT:[[TMP3:%.*]] = and i1 [[TMP2]], [[X:%.*]] -; CHECK-NEXT:[[R:%.*]] = xor i1 [[TMP3]], true +; CHECK-NEXT:[[R1:%.*]] = icmp eq i8 [[TMP1]], 0 +; CHECK-NEXT:[[NOT_X:%.*]] = xor i1 [[X:%.*]], true +; CHECK-NEXT:[[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]] ; CHECK-NEXT:ret i1 [[R]] ; %zx = zext i1 %x to i8 @@ -4454,9 +4454,10 @@ define i1 @zext_bool_and_eq0(i1 %x, i8 %y) { define <2 x i1> @zext_bool_and_eq0_commute(<2 x i1> %x, <2 x i8> %p) { ; CHECK-LABEL: @zext_bool_and_eq0_commute( -; CHECK-NEXT:[[TMP1:%.*]] = trunc <2 x i8> [[P:%.*]] to <2 x i1> -; CHECK-NEXT:[[TMP2:%.*]] = and <2 x i1> [[TMP1]], [[X:%.*]] -; CHECK-NEXT:[[R:%.*]] = xor <2 x i1> [[TMP2]], +; CHECK-NEXT:[[TM
[clang-tools-extra] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw closed https://github.com/llvm/llvm-project/pull/65910 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstCombine] Canonicalize `and(zext(A), B)` into `select A, B & 1, 0` (PR #66740)
https://github.com/dtcxzyw closed https://github.com/llvm/llvm-project/pull/66740 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Canonicalize `and(zext(A), B)` into `select A, B & 1, 0` (PR #66740)
https://github.com/dtcxzyw closed https://github.com/llvm/llvm-project/pull/66740 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
dtcxzyw wrote: Ping. https://github.com/llvm/llvm-project/pull/65852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Eliminate dead li after emitting VSETVLIs (PR #65934)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65934 >From 2fe5756dd4d49580d3a23b0ff1b72535f725915e Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 15:51:46 +0800 Subject: [PATCH 1/4] [RISCV] Eliminate dead li after emitting VSETVLIs --- llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 22 ++--- .../RISCV/rvv/fixed-vectors-masked-gather.ll | 24 --- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp index b42ad269c18de6f..918c96beb29afca 100644 --- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp +++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp @@ -757,7 +757,8 @@ class RISCVInsertVSETVLI : public MachineFunctionPass { bool computeVLVTYPEChanges(const MachineBasicBlock &MBB, VSETVLIInfo &Info) const; void computeIncomingVLVTYPE(const MachineBasicBlock &MBB); - void emitVSETVLIs(MachineBasicBlock &MBB); + void emitVSETVLIs(MachineBasicBlock &MBB, +SmallVectorImpl &DeadVLInstrs); void doLocalPostpass(MachineBasicBlock &MBB); void doPRE(MachineBasicBlock &MBB); void insertReadVL(MachineBasicBlock &MBB); @@ -1216,7 +1217,8 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require, return false; } -void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { +void RISCVInsertVSETVLI::emitVSETVLIs( +MachineBasicBlock &MBB, SmallVectorImpl &DeadVLInstrs) { VSETVLIInfo CurInfo = BlockInfo[MBB.getNumber()].Pred; // Track whether the prefix of the block we've scanned is transparent // (meaning has not yet changed the abstract state). @@ -1255,6 +1257,13 @@ void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI)); if (VLOp.isReg()) { // Erase the AVL operand from the instruction. + if (MachineInstr *MI = MRI->getVRegDef(VLOp.getReg()); + MI && MI->getOpcode() == RISCV::ADDI && + MI->getOperand(1).isReg() && MI->getOperand(2).isImm() && + MI->getOperand(1).getReg() == RISCV::X0 && + MI->getOperand(2).getImm() != 0) +DeadVLInstrs.push_back(MI); + VLOp.setReg(RISCV::NoRegister); VLOp.setIsKill(false); } @@ -1580,8 +1589,9 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { // Phase 2 information to avoid adding vsetvlis before the first vector // instruction in the block if the VL/VTYPE is satisfied by its // predecessors. + SmallVector DeadVLInstrs; for (MachineBasicBlock &MBB : MF) -emitVSETVLIs(MBB); +emitVSETVLIs(MBB, DeadVLInstrs); // Now that all vsetvlis are explicit, go through and do block local // DSE and peephole based demanded fields based transforms. Note that @@ -1592,6 +1602,12 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { for (MachineBasicBlock &MBB : MF) doLocalPostpass(MBB); + // Remove dead LI instructions that set VL. + for (MachineInstr *MI : DeadVLInstrs) { +if (MRI->use_nodbg_empty(MI->getOperand(0).getReg())) + MI->eraseFromParent(); + } + // Once we're fully done rewriting all the instructions, do a final pass // through to check for VSETVLIs which write to an unused destination. // For the non X0, X0 variant, we can replace the destination register diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll index f7352b4659e5a9b..0d306775528ed86 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll @@ -12393,7 +12393,6 @@ define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m ; RV64ZVE32F-NEXT:vmv.x.s a2, v12 ; RV64ZVE32F-NEXT:add a2, a0, a2 ; RV64ZVE32F-NEXT:lbu a2, 0(a2) -; RV64ZVE32F-NEXT:li a3, 32 ; RV64ZVE32F-NEXT:vmv.s.x v12, a2 ; RV64ZVE32F-NEXT:vsetivli zero, 2, e8, m2, tu, ma ; RV64ZVE32F-NEXT:vslideup.vi v10, v12, 1 @@ -12431,7 +12430,6 @@ define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m ; RV64ZVE32F-NEXT:vmv.x.s a2, v14 ; RV64ZVE32F-NEXT:add a2, a0, a2 ; RV64ZVE32F-NEXT:lbu a2, 0(a2) -; RV64ZVE32F-NEXT:li a3, 32 ; RV64ZVE32F-NEXT:vmv.s.x v14, a2 ; RV64ZVE32F-NEXT:vsetivli zero, 6, e8, m2, tu, ma ; RV64ZVE32F-NEXT:vslideup.vi v10, v14, 5 @@ -12455,7 +12453,6 @@ define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m ; RV64ZVE32F-NEXT:vmv.x.s a2, v13 ; RV64ZVE32F-NEXT:add a2, a0, a2 ; RV64ZVE32F-NEXT:lbu a2, 0(a2) -; RV64ZVE32F-NEXT:li a3, 32 ; RV64ZVE32F-NEXT:vmv.s.x v14, a2 ; RV64ZVE32F-NEXT:vsetivli zero, 10, e8, m2, tu, ma ; RV64ZVE32F-NEXT:vslideup.vi v10, v
[clang] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
@@ -6380,7 +6380,71 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); + // icmp eq/ne X, (zext/sext (icmp eq/ne X, C)) + ICmpInst::Predicate Pred1, Pred2; const APInt *C; + Instruction *ExtI; + if (match(&I, m_c_ICmp(Pred1, m_Value(X), + m_CombineAnd(m_Instruction(ExtI), + m_ZExtOrSExt(m_ICmp(Pred2, m_Deferred(X), + m_APInt(C))) { dtcxzyw wrote: Sorry, I accidentally dropped the checks in 70a70fb44d0e628a1cf485e1767ada3eaaa26b0f. https://github.com/llvm/llvm-project/pull/65852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65852 >From d9d8bcbb98e8f5aecb9733329389d61a489bd731 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 23:07:29 +0800 Subject: [PATCH 1/9] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` --- .../InstCombine/InstCombineCompares.cpp | 62 ++ .../test/Transforms/InstCombine/icmp-range.ll | 181 ++ 2 files changed, 243 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 9fdc46fec631679..837b8e6d2619989 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6309,7 +6309,69 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); + ICmpInst::Predicate Pred1, Pred2; const APInt *C; + // icmp eq/ne X, (zext (icmp eq/ne X, C)) + if (match(&I, m_c_ICmp(Pred1, m_Value(X), + m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) && + ICmpInst::isEquality(Pred1) && ICmpInst::isEquality(Pred2)) { +if (C->isZero()) { + if (Pred2 == ICmpInst::ICMP_EQ) { +// icmp eq X, (zext (icmp eq X, 0)) --> false +// icmp ne X, (zext (icmp eq X, 0)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp ne X, 0)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp ne X, 0)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else if (C->isOne()) { + if (Pred2 == ICmpInst::ICMP_NE) { +// icmp eq X, (zext (icmp ne X, 1)) --> false +// icmp ne X, (zext (icmp ne X, 1)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp eq X, 1)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp eq X, 1)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else { + // C != 0 && C != 1 + // icmp eq X, (zext (icmp eq X, C)) --> icmp eq X, 0 + // icmp eq X, (zext (icmp ne X, C)) --> icmp eq X, 1 + // icmp ne X, (zext (icmp eq X, C)) --> icmp ne X, 0 + // icmp ne X, (zext (icmp ne X, C)) --> icmp ne X, 1 + return ICmpInst::Create( + Instruction::ICmp, Pred1, X, + Constant::getIntegerValue( + X->getType(), + APInt(X->getType()->getScalarSizeInBits(), +static_cast(Pred2 == ICmpInst::ICMP_NE; +} + } + if (match(I.getOperand(0), m_c_Add(m_ZExt(m_Value(X)), m_SExt(m_Value(Y && match(I.getOperand(1), m_APInt(C)) && X->getType()->isIntOrIntVectorTy(1) && diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll index 4281e09cb0309c8..15424fce33fdeea 100644 --- a/llvm/test/Transforms/InstCombine/icmp-range.ll +++ b/llvm/test/Transforms/InstCombine/icmp-range.ll @@ -1034,6 +1034,187 @@ define i1 @icmp_ne_bool_1(ptr %ptr) { ret i1 %cmp } +define i1 @icmp_ne_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_eq_zero( +; CHECK-NEXT:ret i1 true +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_ne_zext_ne_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_ne_zero( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 +; CHECK-NEXT:ret i1 [[CMP1]] +; + %cmp = icmp ne i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_eq_zext_eq_zero( +; CHECK-NEXT:ret i1 false +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp eq i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_ne_zero(i32 %
[clang-tools-extra] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65852 >From d9d8bcbb98e8f5aecb9733329389d61a489bd731 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 23:07:29 +0800 Subject: [PATCH 1/9] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` --- .../InstCombine/InstCombineCompares.cpp | 62 ++ .../test/Transforms/InstCombine/icmp-range.ll | 181 ++ 2 files changed, 243 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 9fdc46fec631679..837b8e6d2619989 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6309,7 +6309,69 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); + ICmpInst::Predicate Pred1, Pred2; const APInt *C; + // icmp eq/ne X, (zext (icmp eq/ne X, C)) + if (match(&I, m_c_ICmp(Pred1, m_Value(X), + m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) && + ICmpInst::isEquality(Pred1) && ICmpInst::isEquality(Pred2)) { +if (C->isZero()) { + if (Pred2 == ICmpInst::ICMP_EQ) { +// icmp eq X, (zext (icmp eq X, 0)) --> false +// icmp ne X, (zext (icmp eq X, 0)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp ne X, 0)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp ne X, 0)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else if (C->isOne()) { + if (Pred2 == ICmpInst::ICMP_NE) { +// icmp eq X, (zext (icmp ne X, 1)) --> false +// icmp ne X, (zext (icmp ne X, 1)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp eq X, 1)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp eq X, 1)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else { + // C != 0 && C != 1 + // icmp eq X, (zext (icmp eq X, C)) --> icmp eq X, 0 + // icmp eq X, (zext (icmp ne X, C)) --> icmp eq X, 1 + // icmp ne X, (zext (icmp eq X, C)) --> icmp ne X, 0 + // icmp ne X, (zext (icmp ne X, C)) --> icmp ne X, 1 + return ICmpInst::Create( + Instruction::ICmp, Pred1, X, + Constant::getIntegerValue( + X->getType(), + APInt(X->getType()->getScalarSizeInBits(), +static_cast(Pred2 == ICmpInst::ICMP_NE; +} + } + if (match(I.getOperand(0), m_c_Add(m_ZExt(m_Value(X)), m_SExt(m_Value(Y && match(I.getOperand(1), m_APInt(C)) && X->getType()->isIntOrIntVectorTy(1) && diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll index 4281e09cb0309c8..15424fce33fdeea 100644 --- a/llvm/test/Transforms/InstCombine/icmp-range.ll +++ b/llvm/test/Transforms/InstCombine/icmp-range.ll @@ -1034,6 +1034,187 @@ define i1 @icmp_ne_bool_1(ptr %ptr) { ret i1 %cmp } +define i1 @icmp_ne_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_eq_zero( +; CHECK-NEXT:ret i1 true +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_ne_zext_ne_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_ne_zero( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 +; CHECK-NEXT:ret i1 [[CMP1]] +; + %cmp = icmp ne i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_eq_zext_eq_zero( +; CHECK-NEXT:ret i1 false +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp eq i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_ne_zero(i32 %
[clang] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65852 >From d9d8bcbb98e8f5aecb9733329389d61a489bd731 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 23:07:29 +0800 Subject: [PATCH 1/9] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` --- .../InstCombine/InstCombineCompares.cpp | 62 ++ .../test/Transforms/InstCombine/icmp-range.ll | 181 ++ 2 files changed, 243 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 9fdc46fec631679..837b8e6d2619989 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6309,7 +6309,69 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); + ICmpInst::Predicate Pred1, Pred2; const APInt *C; + // icmp eq/ne X, (zext (icmp eq/ne X, C)) + if (match(&I, m_c_ICmp(Pred1, m_Value(X), + m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) && + ICmpInst::isEquality(Pred1) && ICmpInst::isEquality(Pred2)) { +if (C->isZero()) { + if (Pred2 == ICmpInst::ICMP_EQ) { +// icmp eq X, (zext (icmp eq X, 0)) --> false +// icmp ne X, (zext (icmp eq X, 0)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp ne X, 0)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp ne X, 0)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else if (C->isOne()) { + if (Pred2 == ICmpInst::ICMP_NE) { +// icmp eq X, (zext (icmp ne X, 1)) --> false +// icmp ne X, (zext (icmp ne X, 1)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp eq X, 1)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp eq X, 1)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else { + // C != 0 && C != 1 + // icmp eq X, (zext (icmp eq X, C)) --> icmp eq X, 0 + // icmp eq X, (zext (icmp ne X, C)) --> icmp eq X, 1 + // icmp ne X, (zext (icmp eq X, C)) --> icmp ne X, 0 + // icmp ne X, (zext (icmp ne X, C)) --> icmp ne X, 1 + return ICmpInst::Create( + Instruction::ICmp, Pred1, X, + Constant::getIntegerValue( + X->getType(), + APInt(X->getType()->getScalarSizeInBits(), +static_cast(Pred2 == ICmpInst::ICMP_NE; +} + } + if (match(I.getOperand(0), m_c_Add(m_ZExt(m_Value(X)), m_SExt(m_Value(Y && match(I.getOperand(1), m_APInt(C)) && X->getType()->isIntOrIntVectorTy(1) && diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll index 4281e09cb0309c8..15424fce33fdeea 100644 --- a/llvm/test/Transforms/InstCombine/icmp-range.ll +++ b/llvm/test/Transforms/InstCombine/icmp-range.ll @@ -1034,6 +1034,187 @@ define i1 @icmp_ne_bool_1(ptr %ptr) { ret i1 %cmp } +define i1 @icmp_ne_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_eq_zero( +; CHECK-NEXT:ret i1 true +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_ne_zext_ne_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_ne_zero( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 +; CHECK-NEXT:ret i1 [[CMP1]] +; + %cmp = icmp ne i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_eq_zext_eq_zero( +; CHECK-NEXT:ret i1 false +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp eq i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_ne_zero(i32 %
[clang-tools-extra] [InstCombine] Simplify the pattern `a ne/eq (zext/sext (a ne/eq c))` (PR #65852)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65852 >From d9d8bcbb98e8f5aecb9733329389d61a489bd731 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 23:07:29 +0800 Subject: [PATCH 1/9] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` --- .../InstCombine/InstCombineCompares.cpp | 62 ++ .../test/Transforms/InstCombine/icmp-range.ll | 181 ++ 2 files changed, 243 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 9fdc46fec631679..837b8e6d2619989 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6309,7 +6309,69 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); + ICmpInst::Predicate Pred1, Pred2; const APInt *C; + // icmp eq/ne X, (zext (icmp eq/ne X, C)) + if (match(&I, m_c_ICmp(Pred1, m_Value(X), + m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) && + ICmpInst::isEquality(Pred1) && ICmpInst::isEquality(Pred2)) { +if (C->isZero()) { + if (Pred2 == ICmpInst::ICMP_EQ) { +// icmp eq X, (zext (icmp eq X, 0)) --> false +// icmp ne X, (zext (icmp eq X, 0)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp ne X, 0)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp ne X, 0)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else if (C->isOne()) { + if (Pred2 == ICmpInst::ICMP_NE) { +// icmp eq X, (zext (icmp ne X, 1)) --> false +// icmp ne X, (zext (icmp ne X, 1)) --> true +return replaceInstUsesWith( +I, +Constant::getIntegerValue( +I.getType(), +APInt(1U, static_cast(Pred1 == ICmpInst::ICMP_NE; + } else { +// icmp eq X, (zext (icmp eq X, 1)) --> icmp ult X, 2 +// icmp ne X, (zext (icmp eq X, 1)) --> icmp ugt X, 1 +return ICmpInst::Create( +Instruction::ICmp, +Pred1 == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULT, +X, +Constant::getIntegerValue( +X->getType(), APInt(X->getType()->getScalarSizeInBits(), +Pred1 == ICmpInst::ICMP_NE ? 1 : 2))); + } +} else { + // C != 0 && C != 1 + // icmp eq X, (zext (icmp eq X, C)) --> icmp eq X, 0 + // icmp eq X, (zext (icmp ne X, C)) --> icmp eq X, 1 + // icmp ne X, (zext (icmp eq X, C)) --> icmp ne X, 0 + // icmp ne X, (zext (icmp ne X, C)) --> icmp ne X, 1 + return ICmpInst::Create( + Instruction::ICmp, Pred1, X, + Constant::getIntegerValue( + X->getType(), + APInt(X->getType()->getScalarSizeInBits(), +static_cast(Pred2 == ICmpInst::ICMP_NE; +} + } + if (match(I.getOperand(0), m_c_Add(m_ZExt(m_Value(X)), m_SExt(m_Value(Y && match(I.getOperand(1), m_APInt(C)) && X->getType()->isIntOrIntVectorTy(1) && diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll index 4281e09cb0309c8..15424fce33fdeea 100644 --- a/llvm/test/Transforms/InstCombine/icmp-range.ll +++ b/llvm/test/Transforms/InstCombine/icmp-range.ll @@ -1034,6 +1034,187 @@ define i1 @icmp_ne_bool_1(ptr %ptr) { ret i1 %cmp } +define i1 @icmp_ne_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_eq_zero( +; CHECK-NEXT:ret i1 true +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_ne_zext_ne_zero(i32 %a) { +; CHECK-LABEL: @icmp_ne_zext_ne_zero( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 +; CHECK-NEXT:ret i1 [[CMP1]] +; + %cmp = icmp ne i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp ne i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_eq_zero(i32 %a) { +; CHECK-LABEL: @icmp_eq_zext_eq_zero( +; CHECK-NEXT:ret i1 false +; + %cmp = icmp eq i32 %a, 0 + %conv = zext i1 %cmp to i32 + %cmp1 = icmp eq i32 %conv, %a + ret i1 %cmp1 +} + +define i1 @icmp_eq_zext_ne_zero(i32 %
[clang] [NFC][Clang][RISCV] Fix index typos of riscv-v-spec doc in riscv_vector.td (PR #65944)
@@ -1660,29 +1660,29 @@ let HasMasked = false, MaskedPolicyScheme = NonePolicy in { defm vmsbc : RVVIntMaskOutBuiltinSet; } -// 12.5. Vector Bitwise Logical Instructions +// 11.5. Vector Bitwise Logical Instructions let UnMaskedPolicyScheme = HasPassthruOperand in { defm vand : RVVIntBinBuiltinSet; defm vxor : RVVIntBinBuiltinSet; defm vor : RVVIntBinBuiltinSet; } defm vnot_v : RVVPseudoVNotBuiltin<"vxor", "csil">; -// 12.6. Vector Single-Width Bit Shift Instructions +// 11.6. Vector Single-Width Bit Shift Instructions dtcxzyw wrote: 11.6. Vector Single-Width Shift Instructions https://github.com/llvm/llvm-project/pull/65944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang][RISCV] Fix index typos of riscv-v-spec doc in riscv_vector.td (PR #65944)
@@ -1660,29 +1660,29 @@ let HasMasked = false, MaskedPolicyScheme = NonePolicy in { defm vmsbc : RVVIntMaskOutBuiltinSet; } -// 12.5. Vector Bitwise Logical Instructions +// 11.5. Vector Bitwise Logical Instructions let UnMaskedPolicyScheme = HasPassthruOperand in { defm vand : RVVIntBinBuiltinSet; defm vxor : RVVIntBinBuiltinSet; defm vor : RVVIntBinBuiltinSet; } defm vnot_v : RVVPseudoVNotBuiltin<"vxor", "csil">; -// 12.6. Vector Single-Width Bit Shift Instructions +// 11.6. Vector Single-Width Bit Shift Instructions let UnMaskedPolicyScheme = HasPassthruOperand in { defm vsll : RVVShiftBuiltinSet; defm vsrl : RVVUnsignedShiftBuiltinSet; defm vsra : RVVSignedShiftBuiltinSet; -// 12.7. Vector Narrowing Integer Right Shift Instructions +// 11.7. Vector Narrowing Integer Right Shift Instructions defm vnsrl : RVVUnsignedNShiftBuiltinSet; defm vnsra : RVVSignedNShiftBuiltinSet; } defm vncvt_x_x_w : RVVPseudoVNCVTBuiltin<"vnsrl", "vncvt_x", "csi", [["v", "vw"], ["Uv", "UvUw"]]>; -// 12.8. Vector Integer Comparison Instructions +// 11.8. Vector Integer Comparison Instructions dtcxzyw wrote: 11.8. Vector Integer Compare Instructions https://github.com/llvm/llvm-project/pull/65944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang][RISCV] Fix index typos of riscv-v-spec doc in riscv_vector.td (PR #65944)
@@ -2262,11 +2262,11 @@ defm vmfgt : RVVFloatingMaskOutBuiltinSet; defm vmfge : RVVFloatingMaskOutBuiltinSet; } -// 14.14. Vector Floating-Point Classify Instruction +// 13.14. Vector Floating-Point Classify Instruction let Name = "vfclass_v", UnMaskedPolicyScheme = HasPassthruOperand in def vfclass : RVVOp0Builtin<"Uv", "Uvv", "xfd">; -// 14.15. Vector Floating-Point Merge Instructio +// 13.15. Vector Floating-Point Merge Instructio dtcxzyw wrote: 13.15. Vector Floating-Point Merge Instruction https://github.com/llvm/llvm-project/pull/65944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang][RISCV] Fix typos of riscv-v-spec doc in riscv_vector.td (PR #65944)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang][RISCV] Fix typos of riscv-v-spec doc in riscv_vector.td (PR #65944)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang][RISCV] Fix typos of riscv-v-spec doc in riscv_vector.td (PR #65944)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang][RISCV] Fix typos of riscv-v-spec doc in riscv_vector.td (PR #65944)
https://github.com/dtcxzyw approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/65944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang][RISCV] Fix typos of riscv-v-spec doc in riscv_vector.td (PR #65944)
https://github.com/dtcxzyw closed https://github.com/llvm/llvm-project/pull/65944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65910 >From 9bb817aa40dd9bc1bbb18b4cf4bc079145c8ecaa Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 03:58:02 +0800 Subject: [PATCH] [ValueTracking] Simplify uaddo pattern --- llvm/lib/Analysis/ValueTracking.cpp | 23 .../InstSimplify/and-or-implied-cond.ll | 104 ++ 2 files changed, 127 insertions(+) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index c4153b824c37e0a..5aaff4ee81be969 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8291,6 +8291,29 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC))) return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC); + // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ValueTracking] Simplify uaddo pattern (PR #65910)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65910 >From 9bb817aa40dd9bc1bbb18b4cf4bc079145c8ecaa Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 03:58:02 +0800 Subject: [PATCH] [ValueTracking] Simplify uaddo pattern --- llvm/lib/Analysis/ValueTracking.cpp | 23 .../InstSimplify/and-or-implied-cond.ll | 104 ++ 2 files changed, 127 insertions(+) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index c4153b824c37e0a..5aaff4ee81be969 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8291,6 +8291,29 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC))) return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC); + // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65845 >From 91af70acd72c8e889f542ba6dfff6401b89b2dc5 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 16:47:24 +0800 Subject: [PATCH] [InstCombine] Fix transforms of select (~a | c), a, b and select (c & b), a, b --- .../InstCombine/InstCombineSelect.cpp | 17 +- .../Transforms/InstCombine/select-and-or.ll | 214 +- 2 files changed, 166 insertions(+), 65 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 33d370690e71a8c..7913644d376f80b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -3086,17 +3086,18 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) { m_c_LogicalOr(m_Deferred(A), m_Deferred(B) return BinaryOperator::CreateXor(A, B); - // select (~a | c), a, b -> and a, (or c, freeze(b)) + // select (~a | c), a, b -> select a, (select c, true, b), false if (match(CondVal, m_c_Or(m_Not(m_Specific(TrueVal)), m_Value(C))) && CondVal->hasOneUse()) { -FalseVal = Builder.CreateFreeze(FalseVal); -return BinaryOperator::CreateAnd(TrueVal, Builder.CreateOr(C, FalseVal)); +Value *OrV = Builder.CreateSelect(C, One, FalseVal); +return SelectInst::Create(TrueVal, OrV, Zero); } - // select (~c & b), a, b -> and b, (or freeze(a), c) - if (match(CondVal, m_c_And(m_Not(m_Value(C)), m_Specific(FalseVal))) && - CondVal->hasOneUse()) { -TrueVal = Builder.CreateFreeze(TrueVal); -return BinaryOperator::CreateAnd(FalseVal, Builder.CreateOr(C, TrueVal)); + // select (c & b), a, b -> select b, (select ~c, true, a), false + if (match(CondVal, m_c_And(m_Value(C), m_Specific(FalseVal))) && + CondVal->hasOneUse() && isFreeToInvert(C, C->hasOneUse())) { +Value *NotC = Builder.CreateNot(C); +Value *OrV = Builder.CreateSelect(NotC, One, TrueVal); +return SelectInst::Create(FalseVal, OrV, Zero); } // select (a | c), a, b -> select a, true, (select ~c, b, false) if (match(CondVal, m_c_Or(m_Specific(TrueVal), m_Value(C))) && diff --git a/llvm/test/Transforms/InstCombine/select-and-or.ll b/llvm/test/Transforms/InstCombine/select-and-or.ll index fb78f0affcb8f14..7edcd767b86ecba 100644 --- a/llvm/test/Transforms/InstCombine/select-and-or.ll +++ b/llvm/test/Transforms/InstCombine/select-and-or.ll @@ -453,9 +453,8 @@ define i1 @demorgan_select_infloop2(i1 %L) { define i1 @and_or1(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @and_or1( -; CHECK-NEXT:[[TMP1:%.*]] = freeze i1 [[B:%.*]] -; CHECK-NEXT:[[TMP2:%.*]] = or i1 [[TMP1]], [[C:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP2]], [[A:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %nota = xor i1 %a, true @@ -466,9 +465,8 @@ define i1 @and_or1(i1 %a, i1 %b, i1 %c) { define i1 @and_or2(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @and_or2( -; CHECK-NEXT:[[TMP1:%.*]] = freeze i1 [[A:%.*]] -; CHECK-NEXT:[[TMP2:%.*]] = or i1 [[TMP1]], [[C:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP2]], [[B:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %notc = xor i1 %c, true @@ -477,32 +475,32 @@ define i1 @and_or2(i1 %a, i1 %b, i1 %c) { ret i1 %r } -define i1 @and_or1_bundef(i1 %a, i1 noundef %b, i1 %c) { -; CHECK-LABEL: @and_or1_bundef( -; CHECK-NEXT:[[TMP1:%.*]] = or i1 [[C:%.*]], [[B:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP1]], [[A:%.*]] +define i1 @and_or1_commuted(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @and_or1_commuted( +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %nota = xor i1 %a, true - %cond = or i1 %nota, %c + %cond = or i1 %c, %nota %r = select i1 %cond, i1 %a, i1 %b ret i1 %r } -define i1 @and_or2_aundef(i1 noundef %a, i1 %b, i1 %c) { -; CHECK-LABEL: @and_or2_aundef( -; CHECK-NEXT:[[TMP1:%.*]] = or i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP1]], [[B:%.*]] +define i1 @and_or2_commuted(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @and_or2_commuted( +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %notc = xor i1 %c, true - %cond = and i1 %notc, %b + %cond = and i1 %b, %notc %r = select i1 %cond, i1 %a, i1 %b ret i1 %r } -define i1 @no_and_or1_bundef(i1 %a, i1 noundef %b, i1 %c) { -; CHECK-LABEL: @no_and_or1_bundef( +define i1 @and_or1_mult
[clang] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65845 >From 91af70acd72c8e889f542ba6dfff6401b89b2dc5 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 16:47:24 +0800 Subject: [PATCH] [InstCombine] Fix transforms of select (~a | c), a, b and select (c & b), a, b --- .../InstCombine/InstCombineSelect.cpp | 17 +- .../Transforms/InstCombine/select-and-or.ll | 214 +- 2 files changed, 166 insertions(+), 65 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 33d370690e71a8c..7913644d376f80b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -3086,17 +3086,18 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) { m_c_LogicalOr(m_Deferred(A), m_Deferred(B) return BinaryOperator::CreateXor(A, B); - // select (~a | c), a, b -> and a, (or c, freeze(b)) + // select (~a | c), a, b -> select a, (select c, true, b), false if (match(CondVal, m_c_Or(m_Not(m_Specific(TrueVal)), m_Value(C))) && CondVal->hasOneUse()) { -FalseVal = Builder.CreateFreeze(FalseVal); -return BinaryOperator::CreateAnd(TrueVal, Builder.CreateOr(C, FalseVal)); +Value *OrV = Builder.CreateSelect(C, One, FalseVal); +return SelectInst::Create(TrueVal, OrV, Zero); } - // select (~c & b), a, b -> and b, (or freeze(a), c) - if (match(CondVal, m_c_And(m_Not(m_Value(C)), m_Specific(FalseVal))) && - CondVal->hasOneUse()) { -TrueVal = Builder.CreateFreeze(TrueVal); -return BinaryOperator::CreateAnd(FalseVal, Builder.CreateOr(C, TrueVal)); + // select (c & b), a, b -> select b, (select ~c, true, a), false + if (match(CondVal, m_c_And(m_Value(C), m_Specific(FalseVal))) && + CondVal->hasOneUse() && isFreeToInvert(C, C->hasOneUse())) { +Value *NotC = Builder.CreateNot(C); +Value *OrV = Builder.CreateSelect(NotC, One, TrueVal); +return SelectInst::Create(FalseVal, OrV, Zero); } // select (a | c), a, b -> select a, true, (select ~c, b, false) if (match(CondVal, m_c_Or(m_Specific(TrueVal), m_Value(C))) && diff --git a/llvm/test/Transforms/InstCombine/select-and-or.ll b/llvm/test/Transforms/InstCombine/select-and-or.ll index fb78f0affcb8f14..7edcd767b86ecba 100644 --- a/llvm/test/Transforms/InstCombine/select-and-or.ll +++ b/llvm/test/Transforms/InstCombine/select-and-or.ll @@ -453,9 +453,8 @@ define i1 @demorgan_select_infloop2(i1 %L) { define i1 @and_or1(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @and_or1( -; CHECK-NEXT:[[TMP1:%.*]] = freeze i1 [[B:%.*]] -; CHECK-NEXT:[[TMP2:%.*]] = or i1 [[TMP1]], [[C:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP2]], [[A:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %nota = xor i1 %a, true @@ -466,9 +465,8 @@ define i1 @and_or1(i1 %a, i1 %b, i1 %c) { define i1 @and_or2(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @and_or2( -; CHECK-NEXT:[[TMP1:%.*]] = freeze i1 [[A:%.*]] -; CHECK-NEXT:[[TMP2:%.*]] = or i1 [[TMP1]], [[C:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP2]], [[B:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %notc = xor i1 %c, true @@ -477,32 +475,32 @@ define i1 @and_or2(i1 %a, i1 %b, i1 %c) { ret i1 %r } -define i1 @and_or1_bundef(i1 %a, i1 noundef %b, i1 %c) { -; CHECK-LABEL: @and_or1_bundef( -; CHECK-NEXT:[[TMP1:%.*]] = or i1 [[C:%.*]], [[B:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP1]], [[A:%.*]] +define i1 @and_or1_commuted(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @and_or1_commuted( +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %nota = xor i1 %a, true - %cond = or i1 %nota, %c + %cond = or i1 %c, %nota %r = select i1 %cond, i1 %a, i1 %b ret i1 %r } -define i1 @and_or2_aundef(i1 noundef %a, i1 %b, i1 %c) { -; CHECK-LABEL: @and_or2_aundef( -; CHECK-NEXT:[[TMP1:%.*]] = or i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP1]], [[B:%.*]] +define i1 @and_or2_commuted(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @and_or2_commuted( +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %notc = xor i1 %c, true - %cond = and i1 %notc, %b + %cond = and i1 %b, %notc %r = select i1 %cond, i1 %a, i1 %b ret i1 %r } -define i1 @no_and_or1_bundef(i1 %a, i1 noundef %b, i1 %c) { -; CHECK-LABEL: @no_and_or1_bundef( +define i1 @and_or1_mult
[clang-tools-extra] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65845 >From 91af70acd72c8e889f542ba6dfff6401b89b2dc5 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 16:47:24 +0800 Subject: [PATCH 1/2] [InstCombine] Fix transforms of select (~a | c), a, b and select (c & b), a, b --- .../InstCombine/InstCombineSelect.cpp | 17 +- .../Transforms/InstCombine/select-and-or.ll | 214 +- 2 files changed, 166 insertions(+), 65 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 33d370690e71a8c..7913644d376f80b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -3086,17 +3086,18 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) { m_c_LogicalOr(m_Deferred(A), m_Deferred(B) return BinaryOperator::CreateXor(A, B); - // select (~a | c), a, b -> and a, (or c, freeze(b)) + // select (~a | c), a, b -> select a, (select c, true, b), false if (match(CondVal, m_c_Or(m_Not(m_Specific(TrueVal)), m_Value(C))) && CondVal->hasOneUse()) { -FalseVal = Builder.CreateFreeze(FalseVal); -return BinaryOperator::CreateAnd(TrueVal, Builder.CreateOr(C, FalseVal)); +Value *OrV = Builder.CreateSelect(C, One, FalseVal); +return SelectInst::Create(TrueVal, OrV, Zero); } - // select (~c & b), a, b -> and b, (or freeze(a), c) - if (match(CondVal, m_c_And(m_Not(m_Value(C)), m_Specific(FalseVal))) && - CondVal->hasOneUse()) { -TrueVal = Builder.CreateFreeze(TrueVal); -return BinaryOperator::CreateAnd(FalseVal, Builder.CreateOr(C, TrueVal)); + // select (c & b), a, b -> select b, (select ~c, true, a), false + if (match(CondVal, m_c_And(m_Value(C), m_Specific(FalseVal))) && + CondVal->hasOneUse() && isFreeToInvert(C, C->hasOneUse())) { +Value *NotC = Builder.CreateNot(C); +Value *OrV = Builder.CreateSelect(NotC, One, TrueVal); +return SelectInst::Create(FalseVal, OrV, Zero); } // select (a | c), a, b -> select a, true, (select ~c, b, false) if (match(CondVal, m_c_Or(m_Specific(TrueVal), m_Value(C))) && diff --git a/llvm/test/Transforms/InstCombine/select-and-or.ll b/llvm/test/Transforms/InstCombine/select-and-or.ll index fb78f0affcb8f14..7edcd767b86ecba 100644 --- a/llvm/test/Transforms/InstCombine/select-and-or.ll +++ b/llvm/test/Transforms/InstCombine/select-and-or.ll @@ -453,9 +453,8 @@ define i1 @demorgan_select_infloop2(i1 %L) { define i1 @and_or1(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @and_or1( -; CHECK-NEXT:[[TMP1:%.*]] = freeze i1 [[B:%.*]] -; CHECK-NEXT:[[TMP2:%.*]] = or i1 [[TMP1]], [[C:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP2]], [[A:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %nota = xor i1 %a, true @@ -466,9 +465,8 @@ define i1 @and_or1(i1 %a, i1 %b, i1 %c) { define i1 @and_or2(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @and_or2( -; CHECK-NEXT:[[TMP1:%.*]] = freeze i1 [[A:%.*]] -; CHECK-NEXT:[[TMP2:%.*]] = or i1 [[TMP1]], [[C:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP2]], [[B:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %notc = xor i1 %c, true @@ -477,32 +475,32 @@ define i1 @and_or2(i1 %a, i1 %b, i1 %c) { ret i1 %r } -define i1 @and_or1_bundef(i1 %a, i1 noundef %b, i1 %c) { -; CHECK-LABEL: @and_or1_bundef( -; CHECK-NEXT:[[TMP1:%.*]] = or i1 [[C:%.*]], [[B:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP1]], [[A:%.*]] +define i1 @and_or1_commuted(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @and_or1_commuted( +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %nota = xor i1 %a, true - %cond = or i1 %nota, %c + %cond = or i1 %c, %nota %r = select i1 %cond, i1 %a, i1 %b ret i1 %r } -define i1 @and_or2_aundef(i1 noundef %a, i1 %b, i1 %c) { -; CHECK-LABEL: @and_or2_aundef( -; CHECK-NEXT:[[TMP1:%.*]] = or i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP1]], [[B:%.*]] +define i1 @and_or2_commuted(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @and_or2_commuted( +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %notc = xor i1 %c, true - %cond = and i1 %notc, %b + %cond = and i1 %b, %notc %r = select i1 %cond, i1 %a, i1 %b ret i1 %r } -define i1 @no_and_or1_bundef(i1 %a, i1 noundef %b, i1 %c) { -; CHECK-LABEL: @no_and_or1_bundef( +define i1 @and_or1_
[clang-tools-extra] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65845 >From 91af70acd72c8e889f542ba6dfff6401b89b2dc5 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 9 Sep 2023 16:47:24 +0800 Subject: [PATCH 1/2] [InstCombine] Fix transforms of select (~a | c), a, b and select (c & b), a, b --- .../InstCombine/InstCombineSelect.cpp | 17 +- .../Transforms/InstCombine/select-and-or.ll | 214 +- 2 files changed, 166 insertions(+), 65 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 33d370690e71a8c..7913644d376f80b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -3086,17 +3086,18 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) { m_c_LogicalOr(m_Deferred(A), m_Deferred(B) return BinaryOperator::CreateXor(A, B); - // select (~a | c), a, b -> and a, (or c, freeze(b)) + // select (~a | c), a, b -> select a, (select c, true, b), false if (match(CondVal, m_c_Or(m_Not(m_Specific(TrueVal)), m_Value(C))) && CondVal->hasOneUse()) { -FalseVal = Builder.CreateFreeze(FalseVal); -return BinaryOperator::CreateAnd(TrueVal, Builder.CreateOr(C, FalseVal)); +Value *OrV = Builder.CreateSelect(C, One, FalseVal); +return SelectInst::Create(TrueVal, OrV, Zero); } - // select (~c & b), a, b -> and b, (or freeze(a), c) - if (match(CondVal, m_c_And(m_Not(m_Value(C)), m_Specific(FalseVal))) && - CondVal->hasOneUse()) { -TrueVal = Builder.CreateFreeze(TrueVal); -return BinaryOperator::CreateAnd(FalseVal, Builder.CreateOr(C, TrueVal)); + // select (c & b), a, b -> select b, (select ~c, true, a), false + if (match(CondVal, m_c_And(m_Value(C), m_Specific(FalseVal))) && + CondVal->hasOneUse() && isFreeToInvert(C, C->hasOneUse())) { +Value *NotC = Builder.CreateNot(C); +Value *OrV = Builder.CreateSelect(NotC, One, TrueVal); +return SelectInst::Create(FalseVal, OrV, Zero); } // select (a | c), a, b -> select a, true, (select ~c, b, false) if (match(CondVal, m_c_Or(m_Specific(TrueVal), m_Value(C))) && diff --git a/llvm/test/Transforms/InstCombine/select-and-or.ll b/llvm/test/Transforms/InstCombine/select-and-or.ll index fb78f0affcb8f14..7edcd767b86ecba 100644 --- a/llvm/test/Transforms/InstCombine/select-and-or.ll +++ b/llvm/test/Transforms/InstCombine/select-and-or.ll @@ -453,9 +453,8 @@ define i1 @demorgan_select_infloop2(i1 %L) { define i1 @and_or1(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @and_or1( -; CHECK-NEXT:[[TMP1:%.*]] = freeze i1 [[B:%.*]] -; CHECK-NEXT:[[TMP2:%.*]] = or i1 [[TMP1]], [[C:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP2]], [[A:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %nota = xor i1 %a, true @@ -466,9 +465,8 @@ define i1 @and_or1(i1 %a, i1 %b, i1 %c) { define i1 @and_or2(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @and_or2( -; CHECK-NEXT:[[TMP1:%.*]] = freeze i1 [[A:%.*]] -; CHECK-NEXT:[[TMP2:%.*]] = or i1 [[TMP1]], [[C:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP2]], [[B:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %notc = xor i1 %c, true @@ -477,32 +475,32 @@ define i1 @and_or2(i1 %a, i1 %b, i1 %c) { ret i1 %r } -define i1 @and_or1_bundef(i1 %a, i1 noundef %b, i1 %c) { -; CHECK-LABEL: @and_or1_bundef( -; CHECK-NEXT:[[TMP1:%.*]] = or i1 [[C:%.*]], [[B:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP1]], [[A:%.*]] +define i1 @and_or1_commuted(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @and_or1_commuted( +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %nota = xor i1 %a, true - %cond = or i1 %nota, %c + %cond = or i1 %c, %nota %r = select i1 %cond, i1 %a, i1 %b ret i1 %r } -define i1 @and_or2_aundef(i1 noundef %a, i1 %b, i1 %c) { -; CHECK-LABEL: @and_or2_aundef( -; CHECK-NEXT:[[TMP1:%.*]] = or i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT:[[R:%.*]] = and i1 [[TMP1]], [[B:%.*]] +define i1 @and_or2_commuted(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @and_or2_commuted( +; CHECK-NEXT:[[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT:[[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false ; CHECK-NEXT:ret i1 [[R]] ; %notc = xor i1 %c, true - %cond = and i1 %notc, %b + %cond = and i1 %b, %notc %r = select i1 %cond, i1 %a, i1 %b ret i1 %r } -define i1 @no_and_or1_bundef(i1 %a, i1 noundef %b, i1 %c) { -; CHECK-LABEL: @no_and_or1_bundef( +define i1 @and_or1_
[clang] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65905 >From f178af6d47ce6d982c6568ba6e0db517de124291 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 02:01:12 +0800 Subject: [PATCH] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` --- llvm/lib/Analysis/InstructionSimplify.cpp | 28 ++- llvm/test/Transforms/InstSimplify/compare.ll | 194 ++ .../InstSimplify/maxmin_intrinsics.ll | 97 + 3 files changed, 318 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index d0cc56ebc2be319..734029f1ad0bef5 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3427,7 +3427,7 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS, switch (LBO->getOpcode()) { default: break; -case Instruction::Shl: +case Instruction::Shl: { bool NUW = Q.IIQ.hasNoUnsignedWrap(LBO) && Q.IIQ.hasNoUnsignedWrap(RBO); bool NSW = Q.IIQ.hasNoSignedWrap(LBO) && Q.IIQ.hasNoSignedWrap(RBO); if (!NUW || (ICmpInst::isSigned(Pred) && !NSW) || @@ -3436,6 +3436,32 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS, if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(1), RBO->getOperand(1), Q, MaxRecurse - 1)) return V; + break; +} +// icmp X & C1, X & C2 where (C1 & C2) == C1/C2 +// icmp X | C1, X | C2 where (C1 & C2) == C1/C2 +case Instruction::And: +case Instruction::Or: { + if (ICmpInst::isUnsigned(Pred)) { +const APInt *C1, *C2; +if (match(LBO->getOperand(1), m_APInt(C1)) && +match(RBO->getOperand(1), m_APInt(C2))) { + if (C1->isSubsetOf(*C2)) { +if (Pred == ICmpInst::ICMP_ULE) + return ConstantInt::getTrue(getCompareTy(LHS)); +if (Pred == ICmpInst::ICMP_UGT) + return ConstantInt::getFalse(getCompareTy(LHS)); + } + if (C2->isSubsetOf(*C1)) { +if (Pred == ICmpInst::ICMP_UGE) + return ConstantInt::getTrue(getCompareTy(LHS)); +if (Pred == ICmpInst::ICMP_ULT) + return ConstantInt::getFalse(getCompareTy(LHS)); + } +} + } + break; +} } } diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll index c6c104a41c8be70..d21af97494c88bc 100644 --- a/llvm/test/Transforms/InstSimplify/compare.ll +++ b/llvm/test/Transforms/InstSimplify/compare.ll @@ -1919,6 +1919,200 @@ define i1 @tautological8(i32 %A, i32 %B) { ret i1 %D } +define i1 @tautological9(i32 %A) { +; CHECK-LABEL: @tautological9( +; CHECK-NEXT:ret i1 false +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp ugt i32 %C1, %C2 + ret i1 %D +} + +define <2 x i1> @tautological9_vec(<2 x i32> %A) { +; CHECK-LABEL: @tautological9_vec( +; CHECK-NEXT:ret <2 x i1> zeroinitializer +; + %C1 = and <2 x i32> %A, + %C2 = and <2 x i32> %A, + %D = icmp ugt <2 x i32> %C1, %C2 + ret <2 x i1> %D +} + +define i1 @tautological10(i32 %A) { +; CHECK-LABEL: @tautological10( +; CHECK-NEXT:ret i1 true +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp ule i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautological11(i32 %A) { +; CHECK-LABEL: @tautological11( +; CHECK-NEXT:ret i1 true +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp ule i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautological12(i32 %A) { +; CHECK-LABEL: @tautological12( +; CHECK-NEXT:ret i1 false +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp ugt i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautological13(i32 %A) { +; CHECK-LABEL: @tautological13( +; CHECK-NEXT:ret i1 false +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp ult i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological14(i32 %A) { +; CHECK-LABEL: @tautological14( +; CHECK-NEXT:ret i1 true +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp uge i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological15(i32 %A) { +; CHECK-LABEL: @tautological15( +; CHECK-NEXT:ret i1 true +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp uge i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological16(i32 %A) { +; CHECK-LABEL: @tautological16( +; CHECK-NEXT:ret i1 false +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp ult i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological9_negative(i32 %A) { +; CHECK-LABEL: @tautological9_negative( +; CHECK-NEXT:[[C1:%.*]] = and i32 [[A:%.*]], 1 +; CHECK-NEXT:[[C2:%.*]] = and i32 [[A]], 2 +; CHECK-NEXT:[[D:%.*]] = icmp ugt i32 [[C1]], [[C2]] +; CHECK-NEXT:ret i1 [[D]] +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 2 + %D = icmp ugt i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautologi
[clang-tools-extra] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65905 >From f178af6d47ce6d982c6568ba6e0db517de124291 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 02:01:12 +0800 Subject: [PATCH] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` --- llvm/lib/Analysis/InstructionSimplify.cpp | 28 ++- llvm/test/Transforms/InstSimplify/compare.ll | 194 ++ .../InstSimplify/maxmin_intrinsics.ll | 97 + 3 files changed, 318 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index d0cc56ebc2be319..734029f1ad0bef5 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3427,7 +3427,7 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS, switch (LBO->getOpcode()) { default: break; -case Instruction::Shl: +case Instruction::Shl: { bool NUW = Q.IIQ.hasNoUnsignedWrap(LBO) && Q.IIQ.hasNoUnsignedWrap(RBO); bool NSW = Q.IIQ.hasNoSignedWrap(LBO) && Q.IIQ.hasNoSignedWrap(RBO); if (!NUW || (ICmpInst::isSigned(Pred) && !NSW) || @@ -3436,6 +3436,32 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS, if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(1), RBO->getOperand(1), Q, MaxRecurse - 1)) return V; + break; +} +// icmp X & C1, X & C2 where (C1 & C2) == C1/C2 +// icmp X | C1, X | C2 where (C1 & C2) == C1/C2 +case Instruction::And: +case Instruction::Or: { + if (ICmpInst::isUnsigned(Pred)) { +const APInt *C1, *C2; +if (match(LBO->getOperand(1), m_APInt(C1)) && +match(RBO->getOperand(1), m_APInt(C2))) { + if (C1->isSubsetOf(*C2)) { +if (Pred == ICmpInst::ICMP_ULE) + return ConstantInt::getTrue(getCompareTy(LHS)); +if (Pred == ICmpInst::ICMP_UGT) + return ConstantInt::getFalse(getCompareTy(LHS)); + } + if (C2->isSubsetOf(*C1)) { +if (Pred == ICmpInst::ICMP_UGE) + return ConstantInt::getTrue(getCompareTy(LHS)); +if (Pred == ICmpInst::ICMP_ULT) + return ConstantInt::getFalse(getCompareTy(LHS)); + } +} + } + break; +} } } diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll index c6c104a41c8be70..d21af97494c88bc 100644 --- a/llvm/test/Transforms/InstSimplify/compare.ll +++ b/llvm/test/Transforms/InstSimplify/compare.ll @@ -1919,6 +1919,200 @@ define i1 @tautological8(i32 %A, i32 %B) { ret i1 %D } +define i1 @tautological9(i32 %A) { +; CHECK-LABEL: @tautological9( +; CHECK-NEXT:ret i1 false +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp ugt i32 %C1, %C2 + ret i1 %D +} + +define <2 x i1> @tautological9_vec(<2 x i32> %A) { +; CHECK-LABEL: @tautological9_vec( +; CHECK-NEXT:ret <2 x i1> zeroinitializer +; + %C1 = and <2 x i32> %A, + %C2 = and <2 x i32> %A, + %D = icmp ugt <2 x i32> %C1, %C2 + ret <2 x i1> %D +} + +define i1 @tautological10(i32 %A) { +; CHECK-LABEL: @tautological10( +; CHECK-NEXT:ret i1 true +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp ule i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautological11(i32 %A) { +; CHECK-LABEL: @tautological11( +; CHECK-NEXT:ret i1 true +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp ule i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautological12(i32 %A) { +; CHECK-LABEL: @tautological12( +; CHECK-NEXT:ret i1 false +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp ugt i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautological13(i32 %A) { +; CHECK-LABEL: @tautological13( +; CHECK-NEXT:ret i1 false +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp ult i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological14(i32 %A) { +; CHECK-LABEL: @tautological14( +; CHECK-NEXT:ret i1 true +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp uge i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological15(i32 %A) { +; CHECK-LABEL: @tautological15( +; CHECK-NEXT:ret i1 true +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp uge i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological16(i32 %A) { +; CHECK-LABEL: @tautological16( +; CHECK-NEXT:ret i1 false +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp ult i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological9_negative(i32 %A) { +; CHECK-LABEL: @tautological9_negative( +; CHECK-NEXT:[[C1:%.*]] = and i32 [[A:%.*]], 1 +; CHECK-NEXT:[[C2:%.*]] = and i32 [[A]], 2 +; CHECK-NEXT:[[D:%.*]] = icmp ugt i32 [[C1]], [[C2]] +; CHECK-NEXT:ret i1 [[D]] +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 2 + %D = icmp ugt i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautologi
[clang] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65905 >From f178af6d47ce6d982c6568ba6e0db517de124291 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 11 Sep 2023 02:01:12 +0800 Subject: [PATCH 1/2] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` --- llvm/lib/Analysis/InstructionSimplify.cpp | 28 ++- llvm/test/Transforms/InstSimplify/compare.ll | 194 ++ .../InstSimplify/maxmin_intrinsics.ll | 97 + 3 files changed, 318 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index d0cc56ebc2be319..734029f1ad0bef5 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3427,7 +3427,7 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS, switch (LBO->getOpcode()) { default: break; -case Instruction::Shl: +case Instruction::Shl: { bool NUW = Q.IIQ.hasNoUnsignedWrap(LBO) && Q.IIQ.hasNoUnsignedWrap(RBO); bool NSW = Q.IIQ.hasNoSignedWrap(LBO) && Q.IIQ.hasNoSignedWrap(RBO); if (!NUW || (ICmpInst::isSigned(Pred) && !NSW) || @@ -3436,6 +3436,32 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS, if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(1), RBO->getOperand(1), Q, MaxRecurse - 1)) return V; + break; +} +// icmp X & C1, X & C2 where (C1 & C2) == C1/C2 +// icmp X | C1, X | C2 where (C1 & C2) == C1/C2 +case Instruction::And: +case Instruction::Or: { + if (ICmpInst::isUnsigned(Pred)) { +const APInt *C1, *C2; +if (match(LBO->getOperand(1), m_APInt(C1)) && +match(RBO->getOperand(1), m_APInt(C2))) { + if (C1->isSubsetOf(*C2)) { +if (Pred == ICmpInst::ICMP_ULE) + return ConstantInt::getTrue(getCompareTy(LHS)); +if (Pred == ICmpInst::ICMP_UGT) + return ConstantInt::getFalse(getCompareTy(LHS)); + } + if (C2->isSubsetOf(*C1)) { +if (Pred == ICmpInst::ICMP_UGE) + return ConstantInt::getTrue(getCompareTy(LHS)); +if (Pred == ICmpInst::ICMP_ULT) + return ConstantInt::getFalse(getCompareTy(LHS)); + } +} + } + break; +} } } diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll index c6c104a41c8be70..d21af97494c88bc 100644 --- a/llvm/test/Transforms/InstSimplify/compare.ll +++ b/llvm/test/Transforms/InstSimplify/compare.ll @@ -1919,6 +1919,200 @@ define i1 @tautological8(i32 %A, i32 %B) { ret i1 %D } +define i1 @tautological9(i32 %A) { +; CHECK-LABEL: @tautological9( +; CHECK-NEXT:ret i1 false +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp ugt i32 %C1, %C2 + ret i1 %D +} + +define <2 x i1> @tautological9_vec(<2 x i32> %A) { +; CHECK-LABEL: @tautological9_vec( +; CHECK-NEXT:ret <2 x i1> zeroinitializer +; + %C1 = and <2 x i32> %A, + %C2 = and <2 x i32> %A, + %D = icmp ugt <2 x i32> %C1, %C2 + ret <2 x i1> %D +} + +define i1 @tautological10(i32 %A) { +; CHECK-LABEL: @tautological10( +; CHECK-NEXT:ret i1 true +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp ule i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautological11(i32 %A) { +; CHECK-LABEL: @tautological11( +; CHECK-NEXT:ret i1 true +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp ule i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautological12(i32 %A) { +; CHECK-LABEL: @tautological12( +; CHECK-NEXT:ret i1 false +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp ugt i32 %C1, %C2 + ret i1 %D +} + +define i1 @tautological13(i32 %A) { +; CHECK-LABEL: @tautological13( +; CHECK-NEXT:ret i1 false +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp ult i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological14(i32 %A) { +; CHECK-LABEL: @tautological14( +; CHECK-NEXT:ret i1 true +; + %C1 = or i32 %A, 1 + %C2 = or i32 %A, 3 + %D = icmp uge i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological15(i32 %A) { +; CHECK-LABEL: @tautological15( +; CHECK-NEXT:ret i1 true +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp uge i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological16(i32 %A) { +; CHECK-LABEL: @tautological16( +; CHECK-NEXT:ret i1 false +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 3 + %D = icmp ult i32 %C2, %C1 + ret i1 %D +} + +define i1 @tautological9_negative(i32 %A) { +; CHECK-LABEL: @tautological9_negative( +; CHECK-NEXT:[[C1:%.*]] = and i32 [[A:%.*]], 1 +; CHECK-NEXT:[[C2:%.*]] = and i32 [[A]], 2 +; CHECK-NEXT:[[D:%.*]] = icmp ugt i32 [[C1]], [[C2]] +; CHECK-NEXT:ret i1 [[D]] +; + %C1 = and i32 %A, 1 + %C2 = and i32 %A, 2 + %D = icmp ugt i32 %C1, %C2 + ret i1 %D +} + +define i1 @tauto
[clang-tools-extra] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)
https://github.com/dtcxzyw resolved https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstSimplify] Fold icmp of `X and/or C1` and `X and/or C2` into constant (PR #65905)
https://github.com/dtcxzyw edited https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstSimplify] Fold icmp of `X and/or C1` and `X and/or C2` into constant (PR #65905)
https://github.com/dtcxzyw edited https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstSimplify] Fold icmp of `X and/or C1` and `X and/or C2` into constant (PR #65905)
https://github.com/dtcxzyw edited https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [InstSimplify] Fold icmp of `X and/or C1` and `X and/or C2` into constant (PR #65905)
https://github.com/dtcxzyw edited https://github.com/llvm/llvm-project/pull/65905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [InstCombine] Fix transforms of two select patterns (PR #65845)
https://github.com/dtcxzyw closed https://github.com/llvm/llvm-project/pull/65845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits