From c2d8923fc10af92bf60508c7509aac9010dd23ee Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Mon, 24 Aug 2026 09:53:05 -0400 Subject: [PATCH] import CS llvm-22.1.8-1.el9 --- .gitignore | 4 +- .llvm.metadata | 4 +- ...-funwind-tables-the-default-on-all-a.patch | 27 + ...erts-to-test-added-in-145149-because.patch | 26 - ...Base-Scaled-Reg-does-not-dominate-in.patch | 131 - ...ake-sure-instruction-get-from-SunkAd.patch | 143 - ...-Simplify-AArch64-relocateAlloc.-NFC.patch | 47 + ...-adrp-ldr-relaxation-per-symbol-all-.patch | 416 ++ ...x-buffer-overflow-when-verifying-gc..patch | 88 + ...k-for-cast-when-shufflevector-172443.patch | 137 + ...ling-of-undefs-in-the-PPC-isSplatShu.patch | 67 - ...dition-in-select-of-load-fold-208683.patch | 3977 ++++++++++++++++ ...aligned-VL-VST-s-with-memcpy-memmove.patch | 4156 +++++++++++++++++ ...-in-widening-vector-multiplication-1.patch | 191 + ...pression-for-VPMOV-2M-KMOV-with-tied.patch | 81 + ...-symlink-when-finding-install-prefix.patch | 39 - ...ate-.gnu.build.attributes.-sections-.patch | 87 + SOURCES/0b6a1ef429.patch | 70 + SOURCES/20-131099.patch | 28 - SOURCES/21-146424.patch | 94 - ...4631c1f42dbfce78288b8ae30b5840ed59b3.patch | 276 ++ SPECS/llvm.spec | 697 +-- 22 files changed, 9964 insertions(+), 822 deletions(-) create mode 100644 SOURCES/0001-23-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch delete mode 100644 SOURCES/0001-Add-REQUIRES-asserts-to-test-added-in-145149-because.patch delete mode 100644 SOURCES/0001-CGP-Bail-out-if-Base-Scaled-Reg-does-not-dominate-in.patch delete mode 100644 SOURCES/0001-CodeGenPrepare-Make-sure-instruction-get-from-SunkAd.patch create mode 100644 SOURCES/0001-ELF-Simplify-AArch64-relocateAlloc.-NFC.patch create mode 100644 SOURCES/0001-LLD-AArch64-Make-adrp-ldr-relaxation-per-symbol-all-.patch create mode 100644 SOURCES/0001-LLVM-Verifier-Fix-buffer-overflow-when-verifying-gc..patch create mode 100644 SOURCES/0001-PowerPC-Add-check-for-cast-when-shufflevector-172443.patch delete mode 100644 SOURCES/0001-PowerPC-Fix-handling-of-undefs-in-the-PPC-isSplatShu.patch create mode 100644 SOURCES/0001-SDAG-Freeze-condition-in-select-of-load-fold-208683.patch create mode 100644 SOURCES/0001-SystemZ-Avoid-unaligned-VL-VST-s-with-memcpy-memmove.patch create mode 100644 SOURCES/0001-SystemZ-Fix-code-in-widening-vector-multiplication-1.patch create mode 100644 SOURCES/0001-X86-Fix-EVEX-compression-for-VPMOV-2M-KMOV-with-tied.patch delete mode 100644 SOURCES/0001-cmake-Resolve-symlink-when-finding-install-prefix.patch create mode 100644 SOURCES/0001-lld-ELF-Concatenate-.gnu.build.attributes.-sections-.patch create mode 100644 SOURCES/0b6a1ef429.patch delete mode 100644 SOURCES/20-131099.patch delete mode 100644 SOURCES/21-146424.patch create mode 100644 SOURCES/43cb4631c1f42dbfce78288b8ae30b5840ed59b3.patch diff --git a/.gitignore b/.gitignore index ac8f1f6..76b90c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/llvm-project-21.1.8.src.tar.xz -SOURCES/llvm-project-21.1.8.src.tar.xz.sig +SOURCES/llvm-project-22.1.8.src.tar.xz +SOURCES/llvm-project-22.1.8.src.tar.xz.sig diff --git a/.llvm.metadata b/.llvm.metadata index 7bae3ec..7360f17 100644 --- a/.llvm.metadata +++ b/.llvm.metadata @@ -1,2 +1,2 @@ -a02f43a68bf59be15a61d6ddd0d99bd4973244f4 SOURCES/llvm-project-21.1.8.src.tar.xz -c10b9d8ebce251f8be51eb71378122300fd37de3 SOURCES/llvm-project-21.1.8.src.tar.xz.sig +b8a2cafc2ba8c91cee103f00454a211cdd7144f3 SOURCES/llvm-project-22.1.8.src.tar.xz +1210d061f5c4a883cba76d3ae47347338458141d SOURCES/llvm-project-22.1.8.src.tar.xz.sig diff --git a/SOURCES/0001-23-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch b/SOURCES/0001-23-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch new file mode 100644 index 0000000..c79b55d --- /dev/null +++ b/SOURCES/0001-23-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch @@ -0,0 +1,27 @@ +From 49f827b09db549de62dcaf8b90b3fcb3e08c0ee5 Mon Sep 17 00:00:00 2001 +From: Serge Guelton +Date: Mon, 6 Mar 2023 12:37:48 +0100 +Subject: [PATCH] Make -funwind-tables the default on all archs + +--- + clang/lib/Driver/ToolChains/Gnu.cpp | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp +index 24fbdcffc07b..8fed46b49515 100644 +--- a/clang/lib/Driver/ToolChains/Gnu.cpp ++++ b/clang/lib/Driver/ToolChains/Gnu.cpp +@@ -3082,6 +3082,10 @@ Generic_GCC::getDefaultUnwindTableLevel(const ArgList &Args) const { + case llvm::Triple::riscv64be: + case llvm::Triple::x86: + case llvm::Triple::x86_64: ++ // Enable -funwind-tables on all architectures supported by Fedora: ++ // rhbz#1655546 ++ case llvm::Triple::systemz: ++ case llvm::Triple::arm: + return UnwindTableLevel::Asynchronous; + default: + return UnwindTableLevel::None; +-- +2.39.1 + diff --git a/SOURCES/0001-Add-REQUIRES-asserts-to-test-added-in-145149-because.patch b/SOURCES/0001-Add-REQUIRES-asserts-to-test-added-in-145149-because.patch deleted file mode 100644 index 26f372c..0000000 --- a/SOURCES/0001-Add-REQUIRES-asserts-to-test-added-in-145149-because.patch +++ /dev/null @@ -1,26 +0,0 @@ -From ffc7d5ae2d79f98967943fabb2abfbc1b1e047fd Mon Sep 17 00:00:00 2001 -From: Douglas Yung -Date: Tue, 24 Jun 2025 04:08:34 +0000 -Subject: [PATCH] Add `REQUIRES: asserts` to test added in #145149 because it - uses the `-debug-only=` flag. - -This should fix the test failure when building without asserts. ---- - llvm/test/CodeGen/PowerPC/pr141642.ll | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/llvm/test/CodeGen/PowerPC/pr141642.ll b/llvm/test/CodeGen/PowerPC/pr141642.ll -index 38a706574786..61bda4dfaf53 100644 ---- a/llvm/test/CodeGen/PowerPC/pr141642.ll -+++ b/llvm/test/CodeGen/PowerPC/pr141642.ll -@@ -2,6 +2,7 @@ - ; RUN: FileCheck %s - ; CHECK-NOT: lxvdsx - ; CHECK-NOT: LD_SPLAT -+; REQUIRES: asserts - - define weak_odr dso_local void @unpack(ptr noalias noundef %packed_in) local_unnamed_addr { - entry: --- -2.49.0 - diff --git a/SOURCES/0001-CGP-Bail-out-if-Base-Scaled-Reg-does-not-dominate-in.patch b/SOURCES/0001-CGP-Bail-out-if-Base-Scaled-Reg-does-not-dominate-in.patch deleted file mode 100644 index 0c2d067..0000000 --- a/SOURCES/0001-CGP-Bail-out-if-Base-Scaled-Reg-does-not-dominate-in.patch +++ /dev/null @@ -1,131 +0,0 @@ -From dde30a47313bf52fef02bbcb1de931a8d725659f Mon Sep 17 00:00:00 2001 -From: Florian Hahn -Date: Fri, 6 Jun 2025 12:38:30 +0100 -Subject: [PATCH] [CGP] Bail out if (Base|Scaled)Reg does not dominate insert - point. (#142949) - -(Base|Scaled)Reg may not dominate the chosen insert point, if there are -multiple uses of the address. Bail out if that's the case, otherwise we -will generate invalid IR. - -In some cases, we could probably adjust the insert point or hoist the -(Base|Scaled)Reg. - -Fixes https://github.com/llvm/llvm-project/issues/142830. - -PR: https://github.com/llvm/llvm-project/pull/142949 ---- - llvm/lib/CodeGen/CodeGenPrepare.cpp | 13 +++- - .../X86/sink-addrmode-reg-does-not-geps.ll | 76 +++++++++++++++++++ - 2 files changed, 87 insertions(+), 2 deletions(-) - create mode 100644 llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-reg-does-not-geps.ll - -diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp -index 822ed6283117..32348a899683 100644 ---- a/llvm/lib/CodeGen/CodeGenPrepare.cpp -+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp -@@ -5945,8 +5945,17 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - // The current BB may be optimized multiple times, we can't guarantee the - // reuse of Addr happens later, call findInsertPos to find an appropriate - // insert position. -- IRBuilder<> Builder(MemoryInst->getParent(), -- findInsertPos(Addr, MemoryInst, SunkAddr)); -+ auto InsertPos = findInsertPos(Addr, MemoryInst, SunkAddr); -+ -+ // TODO: Adjust insert point considering (Base|Scaled)Reg if possible. -+ if (!SunkAddr) { -+ auto &DT = getDT(*MemoryInst->getFunction()); -+ if ((AddrMode.BaseReg && !DT.dominates(AddrMode.BaseReg, &*InsertPos)) || -+ (AddrMode.ScaledReg && !DT.dominates(AddrMode.ScaledReg, &*InsertPos))) -+ return Modified; -+ } -+ -+ IRBuilder<> Builder(MemoryInst->getParent(), InsertPos); - - if (SunkAddr) { - LLVM_DEBUG(dbgs() << "CGP: Reusing nonlocal addrmode: " << AddrMode -diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-reg-does-not-geps.ll b/llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-reg-does-not-geps.ll -new file mode 100644 -index 000000000000..1640bafbd0bf ---- /dev/null -+++ b/llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-reg-does-not-geps.ll -@@ -0,0 +1,76 @@ -+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -+; RUN: opt -S -passes='require,function(codegenprepare)' %s | FileCheck %s -+ -+target triple = "x86_64-unknown-linux" -+ -+declare i1 @cond(float) -+ -+define void @scaled_reg_does_not_dominate_insert_point(ptr %src) { -+; CHECK-LABEL: define void @scaled_reg_does_not_dominate_insert_point( -+; CHECK-SAME: ptr [[SRC:%.*]]) { -+; CHECK-NEXT: [[BB:.*]]: -+; CHECK-NEXT: br label %[[LOOP:.*]] -+; CHECK: [[LOOP]]: -+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[BB]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] -+; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 -+; CHECK-NEXT: [[SUNKADDR2:%.*]] = mul i64 [[IV_NEXT]], 2 -+; CHECK-NEXT: [[SUNKADDR3:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[SUNKADDR2]] -+; CHECK-NEXT: [[SUNKADDR4:%.*]] = getelementptr i8, ptr [[SUNKADDR3]], i64 6 -+; CHECK-NEXT: [[L_0:%.*]] = load float, ptr [[SUNKADDR4]], align 4 -+; CHECK-NEXT: [[SUNKADDR:%.*]] = mul i64 [[IV]], 2 -+; CHECK-NEXT: [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[SUNKADDR]] -+; CHECK-NEXT: [[L_1:%.*]] = load float, ptr [[SUNKADDR1]], align 4 -+; CHECK-NEXT: [[TMP0:%.*]] = call i1 @cond(float [[L_0]]) -+; CHECK-NEXT: [[C:%.*]] = call i1 @cond(float [[L_1]]) -+; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] -+; CHECK: [[EXIT]]: -+; CHECK-NEXT: ret void -+; -+bb: -+ %gep.base = getelementptr i8, ptr %src, i64 8 -+ br label %loop -+ -+loop: -+ %iv = phi i64 [ 0, %bb ], [ %iv.next, %loop ] -+ %iv.shl = shl i64 %iv, 1 -+ %gep.shl = getelementptr i8, ptr %gep.base, i64 %iv.shl -+ %gep.sub = getelementptr i8, ptr %gep.shl, i64 -8 -+ %iv.next = add i64 %iv, 1 -+ %l.0 = load float, ptr %gep.shl, align 4 -+ %l.1 = load float, ptr %gep.sub, align 4 -+ call i1 @cond(float %l.0) -+ %c = call i1 @cond(float %l.1) -+ br i1 %c, label %loop, label %exit -+ -+exit: -+ ret void -+} -+ -+define void @check_dt_after_modifying_cfg(ptr %dst, i64 %x, i8 %y, i8 %z) { -+; CHECK-LABEL: define void @check_dt_after_modifying_cfg( -+; CHECK-SAME: ptr [[DST:%.*]], i64 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) { -+; CHECK-NEXT: [[ENTRY:.*]]: -+; CHECK-NEXT: [[OFFSET:%.*]] = lshr i64 [[X]], 2 -+; CHECK-NEXT: [[SEL_FROZEN:%.*]] = freeze i8 [[Z]] -+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[SEL_FROZEN]], 0 -+; CHECK-NEXT: br i1 [[CMP]], label %[[SELECT_END:.*]], label %[[SELECT_FALSE_SINK:.*]] -+; CHECK: [[SELECT_FALSE_SINK]]: -+; CHECK-NEXT: [[SMIN:%.*]] = tail call i8 @llvm.smin.i8(i8 [[Y]], i8 0) -+; CHECK-NEXT: br label %[[SELECT_END]] -+; CHECK: [[SELECT_END]]: -+; CHECK-NEXT: [[SEL:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[SMIN]], %[[SELECT_FALSE_SINK]] ] -+; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr i8, ptr [[DST]], i64 [[OFFSET]] -+; CHECK-NEXT: store i8 [[SEL]], ptr [[SUNKADDR]], align 1 -+; CHECK-NEXT: ret void -+; -+entry: -+ %offset = lshr i64 %x, 2 -+ %gep.dst = getelementptr i8, ptr %dst, i64 %offset -+ %smin = tail call i8 @llvm.smin.i8(i8 %y, i8 0) -+ %cmp = icmp slt i8 %z, 0 -+ %sel = select i1 %cmp, i8 0, i8 %smin -+ store i8 %sel, ptr %gep.dst, align 1 -+ ret void -+} -+ -+declare i8 @llvm.smin.i8(i8, i8) #0 --- -2.50.1 - diff --git a/SOURCES/0001-CodeGenPrepare-Make-sure-instruction-get-from-SunkAd.patch b/SOURCES/0001-CodeGenPrepare-Make-sure-instruction-get-from-SunkAd.patch deleted file mode 100644 index a195bc5..0000000 --- a/SOURCES/0001-CodeGenPrepare-Make-sure-instruction-get-from-SunkAd.patch +++ /dev/null @@ -1,143 +0,0 @@ -From c76137f1cfd5758f6889236d49a65f059e6432ff Mon Sep 17 00:00:00 2001 -From: weiguozhi <57237827+weiguozhi@users.noreply.github.com> -Date: Thu, 15 May 2025 09:27:25 -0700 -Subject: [PATCH] [CodeGenPrepare] Make sure instruction get from SunkAddrs is - before MemoryInst (#139303) - -Function optimizeBlock may do optimizations on a block for multiple -times. In the first iteration of the loop, MemoryInst1 may generate a -sunk instruction and store it into SunkAddrs. In the second iteration of -the loop, MemoryInst2 may use the same address and then it can reuse the -sunk instruction stored in SunkAddrs, but MemoryInst2 may be before -MemoryInst1 and the corresponding sunk instruction. In order to avoid -use before def error, we need to find appropriate insert position for the - sunk instruction. - -Fixes #138208. - -(cherry picked from commit 59c6d70ed8120b8864e5f796e2bf3de5518a0ef0) ---- - llvm/lib/CodeGen/CodeGenPrepare.cpp | 41 ++++++++++++++--- - .../CodeGenPrepare/X86/sink-addr-reuse.ll | 44 +++++++++++++++++++ - 2 files changed, 80 insertions(+), 5 deletions(-) - create mode 100644 llvm/test/Transforms/CodeGenPrepare/X86/sink-addr-reuse.ll - -diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp -index 088062afab17..f779f4b782ae 100644 ---- a/llvm/lib/CodeGen/CodeGenPrepare.cpp -+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp -@@ -5728,6 +5728,35 @@ static bool IsNonLocalValue(Value *V, BasicBlock *BB) { - return false; - } - -+// Find an insert position of Addr for MemoryInst. We can't guarantee MemoryInst -+// is the first instruction that will use Addr. So we need to find the first -+// user of Addr in current BB. -+static BasicBlock::iterator findInsertPos(Value *Addr, Instruction *MemoryInst, -+ Value *SunkAddr) { -+ if (Addr->hasOneUse()) -+ return MemoryInst->getIterator(); -+ -+ // We already have a SunkAddr in current BB, but we may need to insert cast -+ // instruction after it. -+ if (SunkAddr) { -+ if (Instruction *AddrInst = dyn_cast(SunkAddr)) -+ return std::next(AddrInst->getIterator()); -+ } -+ -+ // Find the first user of Addr in current BB. -+ Instruction *Earliest = MemoryInst; -+ for (User *U : Addr->users()) { -+ Instruction *UserInst = dyn_cast(U); -+ if (UserInst && UserInst->getParent() == MemoryInst->getParent()) { -+ if (isa(UserInst) || UserInst->isDebugOrPseudoInst()) -+ continue; -+ if (UserInst->comesBefore(Earliest)) -+ Earliest = UserInst; -+ } -+ } -+ return Earliest->getIterator(); -+} -+ - /// Sink addressing mode computation immediate before MemoryInst if doing so - /// can be done without increasing register pressure. The need for the - /// register pressure constraint means this can end up being an all or nothing -@@ -5852,11 +5881,6 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - return Modified; - } - -- // Insert this computation right after this user. Since our caller is -- // scanning from the top of the BB to the bottom, reuse of the expr are -- // guaranteed to happen later. -- IRBuilder<> Builder(MemoryInst); -- - // Now that we determined the addressing expression we want to use and know - // that we have to sink it into this block. Check to see if we have already - // done this for some other load/store instr in this block. If so, reuse -@@ -5867,6 +5891,13 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - - Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr; - Type *IntPtrTy = DL->getIntPtrType(Addr->getType()); -+ -+ // The current BB may be optimized multiple times, we can't guarantee the -+ // reuse of Addr happens later, call findInsertPos to find an appropriate -+ // insert position. -+ IRBuilder<> Builder(MemoryInst->getParent(), -+ findInsertPos(Addr, MemoryInst, SunkAddr)); -+ - if (SunkAddr) { - LLVM_DEBUG(dbgs() << "CGP: Reusing nonlocal addrmode: " << AddrMode - << " for " << *MemoryInst << "\n"); -diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/sink-addr-reuse.ll b/llvm/test/Transforms/CodeGenPrepare/X86/sink-addr-reuse.ll -new file mode 100644 -index 000000000000..019f31140655 ---- /dev/null -+++ b/llvm/test/Transforms/CodeGenPrepare/X86/sink-addr-reuse.ll -@@ -0,0 +1,44 @@ -+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -+; RUN: opt -S -p 'require,codegenprepare' -cgpp-huge-func=0 < %s | FileCheck %s -+ -+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" -+target triple = "x86_64-grtev4-linux-gnu" -+ -+declare void @g(ptr) -+ -+; %load and %load5 use the same address, %load5 is optimized first, %load is -+; optimized later and reuse the same address computation instruction. We must -+; make sure not to generate use before def error. -+ -+define void @f(ptr %arg) { -+; CHECK-LABEL: define void @f( -+; CHECK-SAME: ptr [[ARG:%.*]]) { -+; CHECK-NEXT: [[BB:.*:]] -+; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr i8, ptr [[ARG]], i64 -64 -+; CHECK-NEXT: call void @g(ptr [[GETELEMENTPTR]]) -+; CHECK-NEXT: [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[ARG]], i64 -64 -+; CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr [[SUNKADDR1]], align 8 -+; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr i8, ptr [[ARG]], i64 -56 -+; CHECK-NEXT: [[LOAD4:%.*]] = load i32, ptr [[SUNKADDR]], align 8 -+; CHECK-NEXT: [[LOAD5:%.*]] = load ptr, ptr [[SUNKADDR1]], align 8 -+; CHECK-NEXT: [[TMP0:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 1, i32 0) -+; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0 -+; CHECK-NEXT: ret void -+; -+bb: -+ %getelementptr = getelementptr i8, ptr %arg, i64 -64 -+ %getelementptr1 = getelementptr i8, ptr %arg, i64 -56 -+ call void @g(ptr %getelementptr) -+ br label %bb3 -+ -+bb3: -+ %load = load ptr, ptr %getelementptr, align 8 -+ %load4 = load i32, ptr %getelementptr1, align 8 -+ %load5 = load ptr, ptr %getelementptr, align 8 -+ %add = add i32 1, 0 -+ %icmp = icmp eq i32 %add, 0 -+ br i1 %icmp, label %bb7, label %bb7 -+ -+bb7: -+ ret void -+} --- -2.49.0 - diff --git a/SOURCES/0001-ELF-Simplify-AArch64-relocateAlloc.-NFC.patch b/SOURCES/0001-ELF-Simplify-AArch64-relocateAlloc.-NFC.patch new file mode 100644 index 0000000..662a9d2 --- /dev/null +++ b/SOURCES/0001-ELF-Simplify-AArch64-relocateAlloc.-NFC.patch @@ -0,0 +1,47 @@ +From e710ff28456c1accbeb3a7e503163233bc615b16 Mon Sep 17 00:00:00 2001 +From: Fangrui Song +Date: Wed, 11 Feb 2026 21:23:34 -0800 +Subject: [PATCH] [ELF] Simplify AArch64::relocateAlloc. NFC + +--- + lld/ELF/Arch/AArch64.cpp | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp +index 55434ae2151c..3c0d4ca64555 100644 +--- a/lld/ELF/Arch/AArch64.cpp ++++ b/lld/ELF/Arch/AArch64.cpp +@@ -931,9 +931,10 @@ static bool needsGotForMemtag(const Relocation &rel) { + + void AArch64::relocateAlloc(InputSection &sec, uint8_t *buf) const { + uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff; +- AArch64Relaxer relaxer(ctx, sec.relocs()); +- for (size_t i = 0, size = sec.relocs().size(); i != size; ++i) { +- const Relocation &rel = sec.relocs()[i]; ++ const ArrayRef relocs = sec.relocs(); ++ AArch64Relaxer relaxer(ctx, relocs); ++ for (size_t i = 0, size = relocs.size(); i != size; ++i) { ++ const Relocation &rel = relocs[i]; + if (rel.expr == R_NONE) // See finalizeAddressDependentContent() + continue; + uint8_t *loc = buf + rel.offset; +@@ -947,14 +948,14 @@ void AArch64::relocateAlloc(InputSection &sec, uint8_t *buf) const { + switch (rel.expr) { + case RE_AARCH64_GOT_PAGE_PC: + if (i + 1 < size && +- relaxer.tryRelaxAdrpLdr(rel, sec.relocs()[i + 1], secAddr, buf)) { ++ relaxer.tryRelaxAdrpLdr(rel, relocs[i + 1], secAddr, buf)) { + ++i; + continue; + } + break; + case RE_AARCH64_PAGE_PC: + if (i + 1 < size && +- relaxer.tryRelaxAdrpAdd(rel, sec.relocs()[i + 1], secAddr, buf)) { ++ relaxer.tryRelaxAdrpAdd(rel, relocs[i + 1], secAddr, buf)) { + ++i; + continue; + } +-- +2.50.1 + diff --git a/SOURCES/0001-LLD-AArch64-Make-adrp-ldr-relaxation-per-symbol-all-.patch b/SOURCES/0001-LLD-AArch64-Make-adrp-ldr-relaxation-per-symbol-all-.patch new file mode 100644 index 0000000..d46ab12 --- /dev/null +++ b/SOURCES/0001-LLD-AArch64-Make-adrp-ldr-relaxation-per-symbol-all-.patch @@ -0,0 +1,416 @@ +From 8d590969badd9f3fed18a99fffbd9afdf3a975c6 Mon Sep 17 00:00:00 2001 +From: Nikita Popov +Date: Fri, 10 Jul 2026 09:09:08 +0200 +Subject: [PATCH] [LLD][AArch64] Make adrp+ldr relaxation per-symbol + all-or-nothing (#208396) + +We can't relax only some adrp+ldr pairs for a symbol, because there may +be a branch target between the adrp and ldr of this form: + + adrp x1, :got:sym + .Lfoo: + ldr x1, [x1, :got_lo12:sym] + # ... + + adrp x1, :got:sym + ldr x2, [x1, :got_lo12:sym] + b .Lfoo + +Relaxing the first adrp+ldr here would be invalid. This was clarified in +the ARM ABI in: +https://github.com/ARM-software/abi-aa/commit/11fb4ef42898060189d6a34ee96966e696ecbd20. + +The implementation already performed a pre-scan to check that the +relevant relocations occur in pairs. Change this scan to a) check all +the preconditions for the relaxation and b) make the decision per +symbol. + +Fixes https://github.com/llvm/llvm-project/issues/138254. +--- + bolt/test/AArch64/got-load-symbolization.s | 11 ++- + bolt/test/AArch64/lite-mode.s | 17 +++-- + lld/ELF/Arch/AArch64.cpp | 83 +++++++++++++-------- + lld/test/ELF/aarch64-adrp-ldr-got.s | 84 +++++++++++++++++++--- + 4 files changed, 149 insertions(+), 46 deletions(-) + +diff --git a/bolt/test/AArch64/got-load-symbolization.s b/bolt/test/AArch64/got-load-symbolization.s +index b4d682688758..399859fd7bfd 100644 +--- a/bolt/test/AArch64/got-load-symbolization.s ++++ b/bolt/test/AArch64/got-load-symbolization.s +@@ -38,9 +38,9 @@ _start: + # CHECK-NEXT: adrp x2, __BOLT_got_zero + # CHECK-NEXT: nop + # CHECK-NEXT: ldr x2, [x2, :lo12:__BOLT_got_zero{{.*}}] +- adrp x2, :got:near ++ adrp x2, :got:near2 + nop +- ldr x2, [x2, :got_lo12:near] ++ ldr x2, [x2, :got_lo12:near2] + + ## Load data object with local visibility. Relaxable into adrp+add. + # CHECK-NEXT: adrp x3, "local_far_data/1" +@@ -58,6 +58,7 @@ _start: + .size _start, .-_start + + .weak near ++.weak near2 + .weak far + .weak far_data + +@@ -77,6 +78,12 @@ near: + ret + .size near, .-near + ++ .globl near2 ++ .type near2, @function ++near2: ++ ret ++.size near2, .-near2 ++ + #--- far.s + + .text +diff --git a/bolt/test/AArch64/lite-mode.s b/bolt/test/AArch64/lite-mode.s +index f2d06219f7a2..24c31772b847 100644 +--- a/bolt/test/AArch64/lite-mode.s ++++ b/bolt/test/AArch64/lite-mode.s +@@ -24,12 +24,12 @@ + # CHECK-COMPACT-NOT: <_start.org.0> + + ## Verify that the number of FDEs matches the number of functions in the output +-## binary. There are three original functions and two optimized. ++## binary. There are four original functions and three optimized. + ## NOTE: at the moment we are emitting extra FDEs for patched functions, thus + ## there is one more FDE for _start. + # RUN: llvm-readelf -u %t.bolt | grep -wc FDE \ + # RUN: | FileCheck --check-prefix=CHECK-FDE %s +-# CHECK-FDE: 6 ++# CHECK-FDE: 8 + + ## In lite mode, optimized code will be separated from the original .text by + ## over 128MB, making it impossible for call/bl instructions in cold functions +@@ -106,9 +106,9 @@ cold_function: + # CHECK-NEXT: add x4 + + ## Check that non-relaxable GOT load is left intact. +- adrp x5, :got:far_func ++ adrp x5, :got:far_func2 + nop +- ldr x5, [x5, #:got_lo12:far_func] ++ ldr x5, [x5, #:got_lo12:far_func2] + # CHECK-INPUT-NEXT: adrp x5 + # CHECK-INPUT-NEXT: nop + # CHECK-INPUT-NEXT: ldr x5 +@@ -155,3 +155,12 @@ far_func: + ret x30 + .cfi_endproc + .size far_func, .-far_func ++ ++ .globl far_func2 ++ .type far_func2, %function ++far_func2: ++# FDATA: 0 [unknown] 0 1 far_func2 0 0 100 ++ .cfi_startproc ++ ret x30 ++ .cfi_endproc ++ .size far_func2, .-far_func2 +diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp +index ed6d42fd4c05..11c3dca1a358 100644 +--- a/lld/ELF/Arch/AArch64.cpp ++++ b/lld/ELF/Arch/AArch64.cpp +@@ -106,13 +106,17 @@ private: + + struct AArch64Relaxer { + Ctx &ctx; +- bool safeToRelaxAdrpLdr = false; ++ SmallPtrSet unsafeToRelaxAdrpLdr; + +- AArch64Relaxer(Ctx &ctx, ArrayRef relocs); ++ AArch64Relaxer(Ctx &ctx, ArrayRef relocs, uint64_t secAddr, ++ uint8_t *buf); + bool tryRelaxAdrpAdd(const Relocation &adrpRel, const Relocation &addRel, + uint64_t secAddr, uint8_t *buf) const; + bool tryRelaxAdrpLdr(const Relocation &adrpRel, const Relocation &ldrRel, + uint64_t secAddr, uint8_t *buf) const; ++ bool isLegalAdrpLdrRelaxationCandidate(const Relocation &adrpRel, ++ const Relocation &ldrRel, ++ uint64_t secAddr, uint8_t *buf) const; + }; + } // namespace + +@@ -896,26 +900,30 @@ void AArch64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, + llvm_unreachable("invalid relocation for TLS IE to LE relaxation"); + } + +-AArch64Relaxer::AArch64Relaxer(Ctx &ctx, ArrayRef relocs) ++AArch64Relaxer::AArch64Relaxer(Ctx &ctx, ArrayRef relocs, ++ uint64_t secAddr, uint8_t *buf) + : ctx(ctx) { + if (!ctx.arg.relax) + return; +- // Check if R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC +- // always appear in pairs. ++ // For a given symbol R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC ++ // relaxation is all-or-nothing. We can't relax only some of them, as there ++ // may be a jump destination between the two relocations. + size_t i = 0; + const size_t size = relocs.size(); + for (; i != size; ++i) { + if (relocs[i].type == R_AARCH64_ADR_GOT_PAGE) { +- if (i + 1 < size && relocs[i + 1].type == R_AARCH64_LD64_GOT_LO12_NC) { ++ if (i + 1 < size && relocs[i + 1].type == R_AARCH64_LD64_GOT_LO12_NC && ++ !unsafeToRelaxAdrpLdr.contains(relocs[i].sym) && ++ isLegalAdrpLdrRelaxationCandidate(relocs[i], relocs[i + 1], secAddr, ++ buf)) { + ++i; + continue; + } +- break; ++ unsafeToRelaxAdrpLdr.insert(relocs[i].sym); + } else if (relocs[i].type == R_AARCH64_LD64_GOT_LO12_NC) { +- break; ++ unsafeToRelaxAdrpLdr.insert(relocs[i].sym); + } + } +- safeToRelaxAdrpLdr = i == size; + } + + bool AArch64Relaxer::tryRelaxAdrpAdd(const Relocation &adrpRel, +@@ -966,23 +974,9 @@ bool AArch64Relaxer::tryRelaxAdrpAdd(const Relocation &adrpRel, + return true; + } + +-bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, +- const Relocation &ldrRel, uint64_t secAddr, +- uint8_t *buf) const { +- if (!safeToRelaxAdrpLdr) +- return false; +- +- // When the definition of sym is not preemptible then we may +- // be able to relax +- // ADRP xn, :got: sym +- // LDR xn, [ xn :got_lo12: sym] +- // to +- // ADRP xn, sym +- // ADD xn, xn, :lo_12: sym +- +- if (adrpRel.type != R_AARCH64_ADR_GOT_PAGE || +- ldrRel.type != R_AARCH64_LD64_GOT_LO12_NC) +- return false; ++bool AArch64Relaxer::isLegalAdrpLdrRelaxationCandidate( ++ const Relocation &adrpRel, const Relocation &ldrRel, uint64_t secAddr, ++ uint8_t *buf) const { + // Check if the relocations apply to consecutive instructions. + if (adrpRel.offset + 4 != ldrRel.offset) + return false; +@@ -1022,10 +1016,37 @@ bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, + if (val != llvm::SignExtend64(val, 33)) + return false; + ++ return true; ++} ++ ++bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, ++ const Relocation &ldrRel, uint64_t secAddr, ++ uint8_t *buf) const { ++ // When the definition of sym is not preemptible then we may ++ // be able to relax ++ // ADRP xn, :got: sym ++ // LDR xn, [ xn :got_lo12: sym] ++ // to ++ // ADRP xn, sym ++ // ADD xn, xn, :lo_12: sym ++ ++ if (!ctx.arg.relax || adrpRel.type != R_AARCH64_ADR_GOT_PAGE || ++ ldrRel.type != R_AARCH64_LD64_GOT_LO12_NC) ++ return false; ++ ++ Symbol *sym = adrpRel.sym; ++ if (unsafeToRelaxAdrpLdr.contains(sym)) ++ return false; ++ ++ assert(isLegalAdrpLdrRelaxationCandidate(adrpRel, ldrRel, secAddr, buf) && ++ "Should have been marked as unsafe"); ++ ++ uint32_t adrpInstr = read32le(buf + adrpRel.offset); ++ uint32_t adrpDestReg = adrpInstr & 0x1f; + Relocation adrpSymRel = {RE_AARCH64_PAGE_PC, R_AARCH64_ADR_PREL_PG_HI21, +- adrpRel.offset, /*addend=*/0, &sym}; ++ adrpRel.offset, /*addend=*/0, sym}; + Relocation addRel = {R_ABS, R_AARCH64_ADD_ABS_LO12_NC, ldrRel.offset, +- /*addend=*/0, &sym}; ++ /*addend=*/0, sym}; + + // adrp x_ + write32le(buf + adrpSymRel.offset, 0x90000000 | adrpDestReg); +@@ -1034,11 +1055,11 @@ bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, + + ctx.target->relocate( + buf + adrpSymRel.offset, adrpSymRel, +- SignExtend64(getAArch64Page(sym.getVA(ctx)) - ++ SignExtend64(getAArch64Page(sym->getVA(ctx)) - + getAArch64Page(secAddr + adrpSymRel.offset), + 64)); + ctx.target->relocate(buf + addRel.offset, addRel, +- SignExtend64(sym.getVA(ctx), 64)); ++ SignExtend64(sym->getVA(ctx), 64)); + tryRelaxAdrpAdd(adrpSymRel, addRel, secAddr, buf); + return true; + } +@@ -1052,7 +1073,7 @@ static bool needsGotForMemtag(const Relocation &rel) { + void AArch64::relocateAlloc(InputSection &sec, uint8_t *buf) const { + uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff; + const ArrayRef relocs = sec.relocs(); +- AArch64Relaxer relaxer(ctx, relocs); ++ AArch64Relaxer relaxer(ctx, relocs, secAddr, buf); + for (size_t i = 0, size = relocs.size(); i != size; ++i) { + const Relocation &rel = relocs[i]; + if (rel.expr == R_NONE) // See finalizeAddressDependentContent() +diff --git a/lld/test/ELF/aarch64-adrp-ldr-got.s b/lld/test/ELF/aarch64-adrp-ldr-got.s +index 56a90aac3876..a8216da9f20c 100644 +--- a/lld/test/ELF/aarch64-adrp-ldr-got.s ++++ b/lld/test/ELF/aarch64-adrp-ldr-got.s +@@ -4,6 +4,7 @@ + # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/a.s -o %t/a.o + # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/unpaired.s -o %t/unpaired.o + # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/lone-ldr.s -o %t/lone-ldr.o ++# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/all-or-nothing.s -o %t/all-or-nothing.o + + # RUN: ld.lld %t/a.o -T %t/out-of-adr-range.t -o %t/a + # RUN: llvm-objdump --no-show-raw-insn -d %t/a | FileCheck %s +@@ -49,7 +50,8 @@ + # RUN: llvm-objdump --no-show-raw-insn -d %t/out-of-range | \ + # RUN: FileCheck --check-prefix=X1-NO-RELAX %s + +-## Relocations do not appear in pairs, no relaxations should be applied. ++## Relocations do not appear in pairs, no relaxations should be applied for ++## that symbol. We can still relax other symbols. + # RUN: ld.lld %t/unpaired.o -o %t/unpaired + # RUN: llvm-objdump --no-show-raw-insn -d %t/unpaired | \ + # RUN: FileCheck --check-prefix=UNPAIRED %s +@@ -58,6 +60,9 @@ + # UNPAIRED-NEXT: b + # UNPAIRED-NEXT: adrp x0 + # UNPAIRED: ldr x0 ++## This is a different symbol. ++# UNPAIRED: nop ++# UNPAIRED: adr x1 + + ## Relocations do not appear in pairs, no relaxations should be applied. + # RUN: ld.lld %t/lone-ldr.o -o %t/lone-ldr +@@ -66,6 +71,26 @@ + + # LONE-LDR: ldr x0 + ++## Make sure that relaxation is not applied if not all adrp+ldr pairs for ++## a given symbol can be relaxed. This is not legal, because there may be ++## a branch destination between the adrp and ldr instructions. We can still ++## perform the relaxation for other symbols, or the same symbol in a different ++## section. ++# RUN: ld.lld %t/all-or-nothing.o -o %t/all-or-nothing ++# RUN: llvm-objdump --no-show-raw-insn -d %t/all-or-nothing | \ ++# RUN: FileCheck --check-prefix=ALL-OR-NOTHING %s ++ ++# ALL-OR-NOTHING-LABEL: <_start>: ++# ALL-OR-NOTHING: adrp x1 ++# ALL-OR-NOTHING: ldr x1 ++# ALL-OR-NOTHING: adrp x1 ++# ALL-OR-NOTHING: ldr x2 ++# ALL-OR-NOTHING: nop ++# ALL-OR-NOTHING: adr x1 ++# ALL-OR-NOTHING-LABEL: : ++# ALL-OR-NOTHING: nop ++# ALL-OR-NOTHING: adr x1 ++ + ## This linker script ensures that .rodata and .text are sufficiently (>1M) + ## far apart so that the adrp + ldr pair cannot be relaxed to adr + nop. + #--- out-of-adr-range.t +@@ -95,25 +120,40 @@ SECTIONS { + .hidden x + x: + .word 10 ++.hidden y ++y: ++.word 10 ++.hidden z ++z: ++.word 10 ++.hidden u ++u: ++.word 10 ++.hidden v ++v: ++.word 10 + .text + .global _start + _start: + adrp x1, :got:x + ldr x1, [x1, #:got_lo12:x] +- adrp x2, :got:x+1 +- ldr x2, [x2, #:got_lo12:x] +- adrp x3, :got:x +- ldr x3, [x3, #:got_lo12:x+8] +- adrp x4, :got:x +- ldr x5, [x4, #:got_lo12:x] +- adrp x6, :got:x +- ldr x6, [x0, #:got_lo12:x] ++ adrp x2, :got:y+1 ++ ldr x2, [x2, #:got_lo12:y] ++ adrp x3, :got:z ++ ldr x3, [x3, #:got_lo12:z+8] ++ adrp x4, :got:u ++ ldr x5, [x4, #:got_lo12:u] ++ adrp x6, :got:v ++ ldr x6, [x0, #:got_lo12:v] + + #--- unpaired.s + .text + .hidden x + x: + nop ++.hidden y ++y: ++ nop + .global _start + _start: + adrp x0, :got:x +@@ -121,6 +161,8 @@ _start: + adrp x0, :got:x + L: + ldr x0, [x0, #:got_lo12:x] ++ adrp x1, :got:y ++ ldr x1, [x1, #:got_lo12:y] + + #--- lone-ldr.s + .text +@@ -130,3 +172,27 @@ x: + .global _start + _start: + ldr x0, [x0, #:got_lo12:x] ++ ++#--- all-or-nothing.s ++.rodata ++.hidden x ++x: ++.word 10 ++.hidden y ++y: ++.word 10 ++.text ++.global _start ++_start: ++ adrp x1, :got:x ++ ldr x1, [x1, #:got_lo12:x] ++ adrp x1, :got:x ++ ldr x2, [x1, #:got_lo12:x] ++ adrp x1, :got:y ++ ldr x1, [x1, #:got_lo12:y] ++ ++.section .text.foo ++.global foo ++foo: ++ adrp x1, :got:x ++ ldr x1, [x1, #:got_lo12:x] +-- +2.50.1 + diff --git a/SOURCES/0001-LLVM-Verifier-Fix-buffer-overflow-when-verifying-gc..patch b/SOURCES/0001-LLVM-Verifier-Fix-buffer-overflow-when-verifying-gc..patch new file mode 100644 index 0000000..1f79e82 --- /dev/null +++ b/SOURCES/0001-LLVM-Verifier-Fix-buffer-overflow-when-verifying-gc..patch @@ -0,0 +1,88 @@ +From 7bb9626d5ab901e5c1a8e9acbbb1684c982401b4 Mon Sep 17 00:00:00 2001 +From: Tulio Magno Quites Machado Filho +Date: Fri, 10 Jul 2026 15:45:02 -0300 +Subject: [PATCH] [LLVM][Verifier] Fix buffer overflow when verifying + gc.statepoint (#208278) + +When a negative base index is passed, the verification detects the +out-of-bounds value and start printing information that helps to +identify what caused the error. In order to print all the information, +it tries to dereference the Base pointer at +GCRelocateInst::getBasePtr(), causing the buffer overflow. Add a bounds +check to getBasePTR() and getDerivedPtr() in order to avoid this. + +Improve the test in order to validate negative values passed as indexes. +They're based on the reproducer from issue #199191. + +Fixes #199191 +--- + llvm/lib/IR/AsmWriter.cpp | 10 ++++++++-- + llvm/lib/IR/IntrinsicInst.cpp | 19 ++++++++++++++++--- + 3 files changed, 40 insertions(+), 5 deletions(-) + +diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp +index e90630a8cae5..6752d6aa344d 100644 +--- a/llvm/lib/IR/AsmWriter.cpp ++++ b/llvm/lib/IR/AsmWriter.cpp +@@ -4372,9 +4372,15 @@ void AssemblyWriter::printInstructionLine(const Instruction &I) { + /// intrinsic indicating base and derived pointer names. + void AssemblyWriter::printGCRelocateComment(const GCRelocateInst &Relocate) { + Out << " ; ("; +- writeOperand(Relocate.getBasePtr(), false); ++ if (Value *BasePtr = Relocate.getBasePtr()) ++ writeOperand(BasePtr, false); ++ else ++ Out << "invalid"; + Out << ", "; +- writeOperand(Relocate.getDerivedPtr(), false); ++ if (Value *DerivedPtr = Relocate.getDerivedPtr()) ++ writeOperand(DerivedPtr, false); ++ else ++ Out << "invalid"; + Out << ")"; + } + +diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp +index 3e9f3257956a..eb964d566f29 100644 +--- a/llvm/lib/IR/IntrinsicInst.cpp ++++ b/llvm/lib/IR/IntrinsicInst.cpp +@@ -867,10 +867,16 @@ Value *GCRelocateInst::getBasePtr() const { + auto Statepoint = getStatepoint(); + if (isa(Statepoint)) + return UndefValue::get(Statepoint->getType()); +- ++ // Handle too few (bundle) arguments to avoid crashes when printing invalid ++ // IR, e.g. in the verifier. + auto *GCInst = cast(Statepoint); +- if (auto Opt = GCInst->getOperandBundle(LLVMContext::OB_gc_live)) ++ if (auto Opt = GCInst->getOperandBundle(LLVMContext::OB_gc_live)) { ++ if (getBasePtrIndex() > Opt->Inputs.size()) ++ return nullptr; + return *(Opt->Inputs.begin() + getBasePtrIndex()); ++ } ++ if (getBasePtrIndex() > GCInst->arg_size()) ++ return nullptr; + return *(GCInst->arg_begin() + getBasePtrIndex()); + } + +@@ -879,9 +885,16 @@ Value *GCRelocateInst::getDerivedPtr() const { + if (isa(Statepoint)) + return UndefValue::get(Statepoint->getType()); + ++ // Handle too few (bundle) arguments to avoid crashes when printing invalid ++ // IR, e.g. in the verifier. + auto *GCInst = cast(Statepoint); +- if (auto Opt = GCInst->getOperandBundle(LLVMContext::OB_gc_live)) ++ if (auto Opt = GCInst->getOperandBundle(LLVMContext::OB_gc_live)) { ++ if (getDerivedPtrIndex() > Opt->Inputs.size()) ++ return nullptr; + return *(Opt->Inputs.begin() + getDerivedPtrIndex()); ++ } ++ if (getDerivedPtrIndex() > GCInst->arg_size()) ++ return nullptr; + return *(GCInst->arg_begin() + getDerivedPtrIndex()); + } + +-- +2.50.1 + diff --git a/SOURCES/0001-PowerPC-Add-check-for-cast-when-shufflevector-172443.patch b/SOURCES/0001-PowerPC-Add-check-for-cast-when-shufflevector-172443.patch new file mode 100644 index 0000000..1f6c0ad --- /dev/null +++ b/SOURCES/0001-PowerPC-Add-check-for-cast-when-shufflevector-172443.patch @@ -0,0 +1,137 @@ +From 98b82f90dfb7865ae4dbfcb5a83a9e817e7894a1 Mon Sep 17 00:00:00 2001 +From: Kevin Per +Date: Thu, 18 Dec 2025 10:14:01 +0100 +Subject: [PATCH] [PowerPC]: Add check for cast when shufflevector (#172443) + +The crash happens because the cast for `Mask = +cast(Res)->getMask();` fails for node `t197: v16i8 += vector_shuffle<16,17,18,19,4,5,6,7,8,9,10,11,u,u,u,u> t196, t196`. +However, both `LHS` and `RHS` are the same node, so +`DAG.getCommutedVectorShuffle` doesn't return a `ShuffleVectorSDNode` +and crashes. The fix is to add a check before the cast is performed. + +Closes https://github.com/llvm/llvm-project/issues/172265 +--- + llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 4 + + .../test/CodeGen/PowerPC/vec_shuffle_le_be.ll | 94 +++++++++++++++++++ + 2 files changed, 98 insertions(+) + create mode 100644 llvm/test/CodeGen/PowerPC/vec_shuffle_le_be.ll + +diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +index 5b1d9f814806..21297b812968 100644 +--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp ++++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +@@ -16886,6 +16886,10 @@ SDValue PPCTargetLowering::combineVectorShuffle(ShuffleVectorSDNode *SVN, + RHS.getOpcode() != ISD::VECTOR_SHUFFLE) { + std::swap(LHS, RHS); + Res = DAG.getCommutedVectorShuffle(*SVN); ++ ++ if (!isa(Res)) ++ return Res; ++ + Mask = cast(Res)->getMask(); + } + +diff --git a/llvm/test/CodeGen/PowerPC/vec_shuffle_le_be.ll b/llvm/test/CodeGen/PowerPC/vec_shuffle_le_be.ll +new file mode 100644 +index 000000000000..24c1e54dd952 +--- /dev/null ++++ b/llvm/test/CodeGen/PowerPC/vec_shuffle_le_be.ll +@@ -0,0 +1,94 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux-gnu | FileCheck -check-prefix=CHECK-LE %s ++; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck -check-prefix=CHECK-BE %s ++ ++define <32 x i32> @issue_172265(<32 x i32> %BS_ARG_1, <3 x i32> %0) { ++; CHECK-LABEL: issue_172265: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addis 3, 2, .LCPI18_0@toc@ha ++; CHECK-NEXT: vspltw 3, 10, 1 ++; CHECK-NEXT: addi 3, 3, .LCPI18_0@toc@l ++; CHECK-NEXT: vmr 7, 3 ++; CHECK-NEXT: lvx 4, 0, 3 ++; CHECK-NEXT: addis 3, 2, .LCPI18_1@toc@ha ++; CHECK-NEXT: addi 3, 3, .LCPI18_1@toc@l ++; CHECK-NEXT: vmr 8, 3 ++; CHECK-NEXT: vmr 9, 3 ++; CHECK-NEXT: vperm 4, 3, 3, 4 ++; CHECK-NEXT: lvx 1, 0, 3 ++; CHECK-NEXT: addis 3, 2, .LCPI18_2@toc@ha ++; CHECK-NEXT: addi 3, 3, .LCPI18_2@toc@l ++; CHECK-NEXT: lvx 5, 0, 3 ++; CHECK-NEXT: addis 3, 2, .LCPI18_3@toc@ha ++; CHECK-NEXT: addi 3, 3, .LCPI18_3@toc@l ++; CHECK-NEXT: lvx 6, 0, 3 ++; CHECK-NEXT: addis 3, 2, .LCPI18_4@toc@ha ++; CHECK-NEXT: addi 3, 3, .LCPI18_4@toc@l ++; CHECK-NEXT: vperm 4, 2, 4, 1 ++; CHECK-NEXT: lvx 2, 0, 3 ++; CHECK-NEXT: vperm 0, 3, 3, 5 ++; CHECK-NEXT: vperm 5, 3, 3, 6 ++; CHECK-NEXT: vperm 6, 3, 3, 2 ++; CHECK-NEXT: vmr 2, 0 ++; CHECK-NEXT: blr ++; CHECK-LE-LABEL: issue_172265: ++; CHECK-LE: # %bb.0: # %entry ++; CHECK-LE-NEXT: addis 3, 2, .LCPI0_0@toc@ha ++; CHECK-LE-NEXT: xxspltw 35, 42, 1 ++; CHECK-LE-NEXT: addi 3, 3, .LCPI0_0@toc@l ++; CHECK-LE-NEXT: vmr 7, 3 ++; CHECK-LE-NEXT: vmr 8, 3 ++; CHECK-LE-NEXT: vmr 9, 3 ++; CHECK-LE-NEXT: lxvd2x 0, 0, 3 ++; CHECK-LE-NEXT: addis 3, 2, .LCPI0_1@toc@ha ++; CHECK-LE-NEXT: addi 3, 3, .LCPI0_1@toc@l ++; CHECK-LE-NEXT: lxvd2x 1, 0, 3 ++; CHECK-LE-NEXT: addis 3, 2, .LCPI0_2@toc@ha ++; CHECK-LE-NEXT: addi 3, 3, .LCPI0_2@toc@l ++; CHECK-LE-NEXT: lxvd2x 2, 0, 3 ++; CHECK-LE-NEXT: addis 3, 2, .LCPI0_3@toc@ha ++; CHECK-LE-NEXT: addi 3, 3, .LCPI0_3@toc@l ++; CHECK-LE-NEXT: xxswapd 36, 0 ++; CHECK-LE-NEXT: lxvd2x 0, 0, 3 ++; CHECK-LE-NEXT: vperm 4, 2, 3, 4 ++; CHECK-LE-NEXT: xxswapd 37, 1 ++; CHECK-LE-NEXT: vperm 2, 3, 3, 5 ++; CHECK-LE-NEXT: xxswapd 32, 2 ++; CHECK-LE-NEXT: vperm 5, 3, 3, 0 ++; CHECK-LE-NEXT: xxswapd 33, 0 ++; CHECK-LE-NEXT: vperm 6, 3, 3, 1 ++; CHECK-LE-NEXT: blr ++; ++; CHECK-BE-LABEL: issue_172265: ++; CHECK-BE: # %bb.0: # %entry ++; CHECK-BE-NEXT: addis 3, 2, .LCPI0_0@toc@ha ++; CHECK-BE-NEXT: vspltw 3, 10, 2 ++; CHECK-BE-NEXT: addi 3, 3, .LCPI0_0@toc@l ++; CHECK-BE-NEXT: vmr 7, 3 ++; CHECK-BE-NEXT: lvx 4, 0, 3 ++; CHECK-BE-NEXT: addis 3, 2, .LCPI0_2@toc@ha ++; CHECK-BE-NEXT: addi 3, 3, .LCPI0_2@toc@l ++; CHECK-BE-NEXT: lvx 5, 0, 3 ++; CHECK-BE-NEXT: addis 3, 2, .LCPI0_3@toc@ha ++; CHECK-BE-NEXT: addi 3, 3, .LCPI0_3@toc@l ++; CHECK-BE-NEXT: vperm 0, 3, 3, 5 ++; CHECK-BE-NEXT: lvx 5, 0, 3 ++; CHECK-BE-NEXT: addis 3, 2, .LCPI0_1@toc@ha ++; CHECK-BE-NEXT: addi 3, 3, .LCPI0_1@toc@l ++; CHECK-BE-NEXT: lvx 1, 0, 3 ++; CHECK-BE-NEXT: addis 3, 2, .LCPI0_4@toc@ha ++; CHECK-BE-NEXT: addi 3, 3, .LCPI0_4@toc@l ++; CHECK-BE-NEXT: vperm 4, 3, 3, 4 ++; CHECK-BE-NEXT: vperm 4, 4, 2, 1 ++; CHECK-BE-NEXT: lvx 2, 0, 3 ++; CHECK-BE-NEXT: vperm 5, 3, 3, 5 ++; CHECK-BE-NEXT: vperm 6, 3, 3, 2 ++; CHECK-BE-NEXT: vmr 2, 0 ++; CHECK-BE-NEXT: vmr 8, 3 ++; CHECK-BE-NEXT: vmr 9, 3 ++; CHECK-BE-NEXT: blr ++entry: ++ %vecinit37 = shufflevector <3 x i32> %0, <3 x i32> zeroinitializer, <32 x i32> ++ %shuffle56 = shufflevector <32 x i32> %vecinit37, <32 x i32> %BS_ARG_1, <32 x i32> ++ ret <32 x i32> %shuffle56 ++} +-- +2.52.0 + diff --git a/SOURCES/0001-PowerPC-Fix-handling-of-undefs-in-the-PPC-isSplatShu.patch b/SOURCES/0001-PowerPC-Fix-handling-of-undefs-in-the-PPC-isSplatShu.patch deleted file mode 100644 index e3d6135..0000000 --- a/SOURCES/0001-PowerPC-Fix-handling-of-undefs-in-the-PPC-isSplatShu.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 735d721de451067c3a618b309703d0b8beb9cacc Mon Sep 17 00:00:00 2001 -From: Wael Yehia -Date: Mon, 23 Jun 2025 13:22:33 -0400 -Subject: [PATCH] [PowerPC] Fix handling of undefs in the - PPC::isSplatShuffleMask query (#145149) - -Currently, the query assumes that a single undef byte implies the rest of -the `EltSize - 1` bytes are undefs, but that's not always true. -e.g. isSplatShuffleMask( -<0,1,2,3,4,5,6,7,undef,undef,undef,undef,0,1,2,3>, 8) should return -false. - ---------- - -Co-authored-by: Wael Yehia ---- - llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 13 +++++++++---- - llvm/test/CodeGen/PowerPC/pr141642.ll | 13 +++++++++++++ - 2 files changed, 22 insertions(+), 4 deletions(-) - create mode 100644 llvm/test/CodeGen/PowerPC/pr141642.ll - -diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp -index 421a808de667..88c6fe632d26 100644 ---- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp -+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp -@@ -2242,10 +2242,15 @@ bool PPC::isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize) { - return false; - - for (unsigned i = EltSize, e = 16; i != e; i += EltSize) { -- if (N->getMaskElt(i) < 0) continue; -- for (unsigned j = 0; j != EltSize; ++j) -- if (N->getMaskElt(i+j) != N->getMaskElt(j)) -- return false; -+ // An UNDEF element is a sequence of UNDEF bytes. -+ if (N->getMaskElt(i) < 0) { -+ for (unsigned j = 1; j != EltSize; ++j) -+ if (N->getMaskElt(i + j) >= 0) -+ return false; -+ } else -+ for (unsigned j = 0; j != EltSize; ++j) -+ if (N->getMaskElt(i + j) != N->getMaskElt(j)) -+ return false; - } - return true; - } -diff --git a/llvm/test/CodeGen/PowerPC/pr141642.ll b/llvm/test/CodeGen/PowerPC/pr141642.ll -new file mode 100644 -index 000000000000..38a706574786 ---- /dev/null -+++ b/llvm/test/CodeGen/PowerPC/pr141642.ll -@@ -0,0 +1,13 @@ -+; RUN: llc -mcpu=pwr8 -mtriple=powerpc64le-unknown-linux-gnu -O0 -debug-only=selectiondag -o - < %s 2>&1 | \ -+; RUN: FileCheck %s -+; CHECK-NOT: lxvdsx -+; CHECK-NOT: LD_SPLAT -+ -+define weak_odr dso_local void @unpack(ptr noalias noundef %packed_in) local_unnamed_addr { -+entry: -+ %ld = load <2 x i32>, ptr %packed_in, align 2 -+ %shuf = shufflevector <2 x i32> %ld, <2 x i32> poison, <4 x i32> -+ %ie = insertelement <4 x i32> %shuf, i32 7, i32 2 -+ store <4 x i32> %shuf, ptr %packed_in, align 2 -+ ret void -+} --- -2.49.0 - diff --git a/SOURCES/0001-SDAG-Freeze-condition-in-select-of-load-fold-208683.patch b/SOURCES/0001-SDAG-Freeze-condition-in-select-of-load-fold-208683.patch new file mode 100644 index 0000000..d15a946 --- /dev/null +++ b/SOURCES/0001-SDAG-Freeze-condition-in-select-of-load-fold-208683.patch @@ -0,0 +1,3977 @@ +From abcef279cd33492fe8301c8873fc535fa4dbf0d5 Mon Sep 17 00:00:00 2001 +From: Nikita Popov +Date: Fri, 10 Jul 2026 16:08:02 +0200 +Subject: [PATCH] [SDAG] Freeze condition in select of load fold (#208683) + +When converting `select cond, (load p1), (load p2)` to `load (select +cond, p1, p2)`, if `cond` is poison, originally this would result in a +`poison` result, while after the transform it would result in a load of +poison, which is immediate UB. Fix this by freezing the condition. + +Fixes https://github.com/llvm/llvm-project/issues/208611. + +(cherry picked from commit f2dfbf06f7db1a3cace4beb9f65d5a7f6a8b6235) +--- + llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 +- + llvm/test/CodeGen/AArch64/icmp.ll | 26 +- + llvm/test/CodeGen/ARM/fp16-promote.ll | 2 +- + llvm/test/CodeGen/Mips/cconv/vector.ll | 10 +- + llvm/test/CodeGen/Mips/cmov.ll | 2 +- + llvm/test/CodeGen/NVPTX/i1-select.ll | 14 +- + .../CodeGen/X86/fp-strict-scalar-cmp-fp16.ll | 112 +- + llvm/test/CodeGen/X86/fp-strict-scalar-cmp.ll | 968 +++++++++++++----- + .../test/CodeGen/X86/fp128-libcalls-strict.ll | 2 + + .../CodeGen/X86/fp80-strict-scalar-cmp.ll | 148 ++- + llvm/test/CodeGen/X86/isel-select-cmov.ll | 16 +- + llvm/test/CodeGen/X86/select-constant-xor.ll | 12 +- + llvm/test/CodeGen/X86/select-mmx.ll | 4 +- + .../test/CodeGen/X86/select-of-load-poison.ll | 20 + + 14 files changed, 994 insertions(+), 358 deletions(-) + create mode 100644 llvm/test/CodeGen/X86/select-of-load-poison.ll + +diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +index ee9238753735a..dec92eff5bc19 100644 +--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp ++++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +@@ -29318,10 +29318,12 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, + SDNode::hasPredecessorHelper(RLD, Visited, Worklist))) + return false; + +- Addr = DAG.getSelect(SDLoc(TheSelect), +- LLD->getBasePtr().getValueType(), +- TheSelect->getOperand(0), LLD->getBasePtr(), +- RLD->getBasePtr()); ++ // If the condition is poison, originally this would result in a poison ++ // result. After the transform, this would result in a load of poison, ++ // which is UB. Freeze the condition to prevent this. ++ Addr = DAG.getSelect(SDLoc(TheSelect), LLD->getBasePtr().getValueType(), ++ DAG.getFreeze(TheSelect->getOperand(0)), ++ LLD->getBasePtr(), RLD->getBasePtr()); + } else { // Otherwise SELECT_CC + // We cannot do this optimization if any pair of {RLD, LLD} is a + // predecessor to {RLD, LLD, CondLHS, CondRHS}. As we've already compared +@@ -29340,10 +29342,10 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, + SDNode::hasPredecessorHelper(RLD, Visited, Worklist))) + return false; + ++ SDValue FrozenOp0 = DAG.getFreeze(TheSelect->getOperand(0)); ++ SDValue FrozenOp1 = DAG.getFreeze(TheSelect->getOperand(1)); + Addr = DAG.getNode(ISD::SELECT_CC, SDLoc(TheSelect), +- LLD->getBasePtr().getValueType(), +- TheSelect->getOperand(0), +- TheSelect->getOperand(1), ++ LLD->getBasePtr().getValueType(), FrozenOp0, FrozenOp1, + LLD->getBasePtr(), RLD->getBasePtr(), + TheSelect->getOperand(4)); + } +diff --git a/llvm/test/CodeGen/AArch64/icmp.ll b/llvm/test/CodeGen/AArch64/icmp.ll +index 7195e2b2f1255..920d5a090c303 100644 +--- a/llvm/test/CodeGen/AArch64/icmp.ll ++++ b/llvm/test/CodeGen/AArch64/icmp.ll +@@ -1379,26 +1379,22 @@ entry: + define <2 x i128> @v2i128_i128(<2 x i128> %a, <2 x i128> %b, <2 x i128> %d, <2 x i128> %e) { + ; CHECK-SD-LABEL: v2i128_i128: + ; CHECK-SD: // %bb.0: // %entry ++; CHECK-SD-NEXT: cmp x2, x6 + ; CHECK-SD-NEXT: add x10, sp, #32 + ; CHECK-SD-NEXT: mov x11, sp ++; CHECK-SD-NEXT: sbcs xzr, x3, x7 ++; CHECK-SD-NEXT: cset w8, lt + ; CHECK-SD-NEXT: cmp x0, x4 +-; CHECK-SD-NEXT: orr x12, x10, #0x8 +-; CHECK-SD-NEXT: orr x13, x11, #0x8 + ; CHECK-SD-NEXT: sbcs xzr, x1, x5 ++; CHECK-SD-NEXT: cset w9, lt ++; CHECK-SD-NEXT: cmp w9, #0 ++; CHECK-SD-NEXT: csel x9, x11, x10, ne ++; CHECK-SD-NEXT: cmp w8, #0 + ; CHECK-SD-NEXT: add x8, sp, #48 +-; CHECK-SD-NEXT: add x9, sp, #16 +-; CHECK-SD-NEXT: csel x12, x13, x12, lt +-; CHECK-SD-NEXT: csel x10, x11, x10, lt +-; CHECK-SD-NEXT: cmp x2, x6 +-; CHECK-SD-NEXT: orr x11, x8, #0x8 +-; CHECK-SD-NEXT: orr x13, x9, #0x8 +-; CHECK-SD-NEXT: sbcs xzr, x3, x7 +-; CHECK-SD-NEXT: ldr x0, [x10] +-; CHECK-SD-NEXT: csel x8, x9, x8, lt +-; CHECK-SD-NEXT: csel x9, x13, x11, lt +-; CHECK-SD-NEXT: ldr x1, [x12] +-; CHECK-SD-NEXT: ldr x2, [x8] +-; CHECK-SD-NEXT: ldr x3, [x9] ++; CHECK-SD-NEXT: add x10, sp, #16 ++; CHECK-SD-NEXT: ldp x0, x1, [x9] ++; CHECK-SD-NEXT: csel x8, x10, x8, ne ++; CHECK-SD-NEXT: ldp x2, x3, [x8] + ; CHECK-SD-NEXT: ret + ; + ; CHECK-GI-LABEL: v2i128_i128: +diff --git a/llvm/test/CodeGen/ARM/fp16-promote.ll b/llvm/test/CodeGen/ARM/fp16-promote.ll +index 27a0bf2eb9037..5b3539def98a0 100644 +--- a/llvm/test/CodeGen/ARM/fp16-promote.ll ++++ b/llvm/test/CodeGen/ARM/fp16-promote.ll +@@ -348,7 +348,7 @@ define half @test_tailcall_flipped(half %a, half %b) #0 { + ; No conversion is needed + define void @test_select(ptr %p, ptr %q, i1 zeroext %c) #0 { + ; CHECK-ALL-LABEL: test_select: +-; CHECK-ALL: cmp r2, #0 ++; CHECK-ALL: tst r2, #1 + ; CHECK-ALL-NEXT: movne r1, r0 + ; CHECK-ALL-NEXT: ldrh r1, [r1] + ; CHECK-ALL-NEXT: strh r1, [r0] +diff --git a/llvm/test/CodeGen/Mips/cconv/vector.ll b/llvm/test/CodeGen/Mips/cconv/vector.ll +index c64c60ddef73d..5cd2b77615fcd 100644 +--- a/llvm/test/CodeGen/Mips/cconv/vector.ll ++++ b/llvm/test/CodeGen/Mips/cconv/vector.ll +@@ -6038,15 +6038,15 @@ entry: + define <4 x float> @select(<4 x i32> %cond, <4 x float> %arg1, <4 x float> %arg2) { + ; MIPS32-LABEL: select: + ; MIPS32: # %bb.0: # %entry +-; MIPS32-NEXT: andi $1, $7, 1 +-; MIPS32-NEXT: lw $2, 16($sp) +-; MIPS32-NEXT: andi $2, $2, 1 ++; MIPS32-NEXT: lw $1, 16($sp) ++; MIPS32-NEXT: andi $2, $7, 1 ++; MIPS32-NEXT: andi $1, $1, 1 + ; MIPS32-NEXT: addiu $3, $sp, 44 + ; MIPS32-NEXT: addiu $5, $sp, 28 + ; MIPS32-NEXT: addiu $7, $sp, 48 + ; MIPS32-NEXT: addiu $8, $sp, 32 +-; MIPS32-NEXT: movn $7, $8, $2 +-; MIPS32-NEXT: movn $3, $5, $1 ++; MIPS32-NEXT: movn $7, $8, $1 ++; MIPS32-NEXT: movn $3, $5, $2 + ; MIPS32-NEXT: andi $1, $6, 1 + ; MIPS32-NEXT: addiu $2, $sp, 40 + ; MIPS32-NEXT: addiu $5, $sp, 24 +diff --git a/llvm/test/CodeGen/Mips/cmov.ll b/llvm/test/CodeGen/Mips/cmov.ll +index bb3c7c27a122d..ee60b353b86b6 100644 +--- a/llvm/test/CodeGen/Mips/cmov.ll ++++ b/llvm/test/CodeGen/Mips/cmov.ll +@@ -65,7 +65,7 @@ entry: + + ; 64-CMOV: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) + ; 64-CMOV: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) +-; 64-CMOV: movn $[[R1]], $[[R0]], $4 ++; 64-CMOV: movn $[[R1]], $[[R0]], $2 + + ; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) + ; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) +diff --git a/llvm/test/CodeGen/NVPTX/i1-select.ll b/llvm/test/CodeGen/NVPTX/i1-select.ll +index c91a3df204d80..c13e494c3077a 100644 +--- a/llvm/test/CodeGen/NVPTX/i1-select.ll ++++ b/llvm/test/CodeGen/NVPTX/i1-select.ll +@@ -70,9 +70,9 @@ define i32 @test_select_i1_trunc_2(i64 %a, i16 %b, i32 %c, i32 %true, i32 %false + define i32 @test_select_i1_basic(i32 %v1, i32 %v2, i32 %v3, i32 %true, i32 %false) { + ; CHECK-LABEL: test_select_i1_basic( + ; CHECK: { +-; CHECK-NEXT: .reg .pred %p<4>; ++; CHECK-NEXT: .reg .pred %p<6>; + ; CHECK-NEXT: .reg .b32 %r<6>; +-; CHECK-NEXT: .reg .b64 %rd<6>; ++; CHECK-NEXT: .reg .b64 %rd<4>; + ; CHECK-EMPTY: + ; CHECK-NEXT: // %bb.0: + ; CHECK-NEXT: ld.param.b32 %r1, [test_select_i1_basic_param_0]; +@@ -81,13 +81,13 @@ define i32 @test_select_i1_basic(i32 %v1, i32 %v2, i32 %v3, i32 %true, i32 %fals + ; CHECK-NEXT: setp.ne.b32 %p1, %r1, 0; + ; CHECK-NEXT: ld.param.b32 %r4, [test_select_i1_basic_param_2]; + ; CHECK-NEXT: setp.eq.b32 %p2, %r4, 0; +-; CHECK-NEXT: setp.eq.b32 %p3, %r3, 0; ++; CHECK-NEXT: and.pred %p3, %p1, %p2; ++; CHECK-NEXT: setp.eq.b32 %p4, %r3, 0; ++; CHECK-NEXT: or.pred %p5, %p4, %p3; + ; CHECK-NEXT: mov.b64 %rd1, test_select_i1_basic_param_4; + ; CHECK-NEXT: mov.b64 %rd2, test_select_i1_basic_param_3; +-; CHECK-NEXT: selp.b64 %rd3, %rd2, %rd1, %p2; +-; CHECK-NEXT: selp.b64 %rd4, %rd3, %rd1, %p1; +-; CHECK-NEXT: selp.b64 %rd5, %rd2, %rd4, %p3; +-; CHECK-NEXT: ld.param.b32 %r5, [%rd5]; ++; CHECK-NEXT: selp.b64 %rd3, %rd2, %rd1, %p5; ++; CHECK-NEXT: ld.param.b32 %r5, [%rd3]; + ; CHECK-NEXT: st.param.b32 [func_retval0], %r5; + ; CHECK-NEXT: ret; + %b1 = icmp eq i32 %v1, 0 +diff --git a/llvm/test/CodeGen/X86/fp-strict-scalar-cmp-fp16.ll b/llvm/test/CodeGen/X86/fp-strict-scalar-cmp-fp16.ll +index 6a6b86e8efa7c..1c06160584f92 100644 +--- a/llvm/test/CodeGen/X86/fp-strict-scalar-cmp-fp16.ll ++++ b/llvm/test/CodeGen/X86/fp-strict-scalar-cmp-fp16.ll +@@ -49,10 +49,13 @@ define i32 @test_f16_oeq_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setnp %al ++; X86-FP16-NEXT: sete %cl ++; X86-FP16-NEXT: andb %al, %cl ++; X86-FP16-NEXT: testb $1, %cl + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X86-FP16-NEXT: cmovnel %eax, %ecx +-; X86-FP16-NEXT: cmovpl %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -112,9 +115,11 @@ define i32 @test_f16_ogt_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: seta %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmoval %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -173,9 +178,11 @@ define i32 @test_f16_oge_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setae %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovael %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -236,9 +243,11 @@ define i32 @test_f16_olt_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: seta %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmoval %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -299,9 +308,11 @@ define i32 @test_f16_ole_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setae %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovael %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -360,6 +371,8 @@ define i32 @test_f16_one_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setne %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X86-FP16-NEXT: cmovnel %eax, %ecx +@@ -421,9 +434,11 @@ define i32 @test_f16_ord_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setnp %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovnpl %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -482,9 +497,11 @@ define i32 @test_f16_ueq_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: sete %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovel %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -545,9 +562,11 @@ define i32 @test_f16_ugt_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setb %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovbl %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -608,9 +627,11 @@ define i32 @test_f16_uge_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setbe %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovbel %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -669,9 +690,11 @@ define i32 @test_f16_ult_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setb %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovbl %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -730,9 +753,11 @@ define i32 @test_f16_ule_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setbe %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovbel %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -793,10 +818,13 @@ define i32 @test_f16_une_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setp %al ++; X86-FP16-NEXT: setne %cl ++; X86-FP16-NEXT: orb %al, %cl ++; X86-FP16-NEXT: testb $1, %cl + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X86-FP16-NEXT: cmovnel %eax, %ecx +-; X86-FP16-NEXT: cmovpl %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -856,9 +884,11 @@ define i32 @test_f16_uno_q(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setp %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovpl %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -919,10 +949,13 @@ define i32 @test_f16_oeq_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setnp %al ++; X86-FP16-NEXT: sete %cl ++; X86-FP16-NEXT: andb %al, %cl ++; X86-FP16-NEXT: testb $1, %cl + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X86-FP16-NEXT: cmovnel %eax, %ecx +-; X86-FP16-NEXT: cmovpl %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -982,9 +1015,11 @@ define i32 @test_f16_ogt_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: seta %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmoval %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1043,9 +1078,11 @@ define i32 @test_f16_oge_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setae %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovael %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1106,9 +1143,11 @@ define i32 @test_f16_olt_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: seta %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmoval %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1169,9 +1208,11 @@ define i32 @test_f16_ole_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setae %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovael %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1230,6 +1271,8 @@ define i32 @test_f16_one_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setne %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X86-FP16-NEXT: cmovnel %eax, %ecx +@@ -1291,9 +1334,11 @@ define i32 @test_f16_ord_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setnp %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovnpl %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1352,9 +1397,11 @@ define i32 @test_f16_ueq_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: sete %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovel %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1415,9 +1462,11 @@ define i32 @test_f16_ugt_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setb %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovbl %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1478,9 +1527,11 @@ define i32 @test_f16_uge_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setbe %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovbel %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1539,9 +1590,11 @@ define i32 @test_f16_ult_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setb %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovbl %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1600,9 +1653,11 @@ define i32 @test_f16_ule_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setbe %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovbel %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1663,10 +1718,13 @@ define i32 @test_f16_une_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setp %al ++; X86-FP16-NEXT: setne %cl ++; X86-FP16-NEXT: orb %al, %cl ++; X86-FP16-NEXT: testb $1, %cl + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X86-FP16-NEXT: cmovnel %eax, %ecx +-; X86-FP16-NEXT: cmovpl %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +@@ -1726,9 +1784,11 @@ define i32 @test_f16_uno_s(i32 %a, i32 %b, half %f1, half %f2) #0 { + ; X86-FP16: # %bb.0: + ; X86-FP16-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero + ; X86-FP16-NEXT: vcomish {{[0-9]+}}(%esp), %xmm0 ++; X86-FP16-NEXT: setp %al ++; X86-FP16-NEXT: testb $1, %al + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-FP16-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X86-FP16-NEXT: cmovpl %eax, %ecx ++; X86-FP16-NEXT: cmovnel %eax, %ecx + ; X86-FP16-NEXT: movl (%ecx), %eax + ; X86-FP16-NEXT: retl + ; +diff --git a/llvm/test/CodeGen/X86/fp-strict-scalar-cmp.ll b/llvm/test/CodeGen/X86/fp-strict-scalar-cmp.ll +index e3e2b6225a7ba..b9823fd5646cc 100644 +--- a/llvm/test/CodeGen/X86/fp-strict-scalar-cmp.ll ++++ b/llvm/test/CodeGen/X86/fp-strict-scalar-cmp.ll +@@ -13,10 +13,13 @@ define i32 @test_f32_oeq_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setnp %al ++; SSE-32-NEXT: sete %cl ++; SSE-32-NEXT: andb %al, %cl ++; SSE-32-NEXT: testb $1, %cl + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -32,10 +35,13 @@ define i32 @test_f32_oeq_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setnp %al ++; AVX-32-NEXT: sete %cl ++; AVX-32-NEXT: andb %al, %cl ++; AVX-32-NEXT: testb $1, %cl + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -56,13 +62,17 @@ define i32 @test_f32_oeq_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: jne .LBB0_3 +-; X87-NEXT: # %bb.1: +-; X87-NEXT: jp .LBB0_3 ++; X87-NEXT: setnp %al ++; X87-NEXT: sete %cl ++; X87-NEXT: andb %al, %cl ++; X87-NEXT: testb $1, %cl ++; X87-NEXT: jne .LBB0_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: .LBB0_3: ++; X87-NEXT: movl (%eax), %eax ++; X87-NEXT: retl ++; X87-NEXT: .LBB0_1: ++; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax + ; X87-NEXT: retl + ; +@@ -73,10 +83,13 @@ define i32 @test_f32_oeq_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setnp %al ++; X87-CMOV-NEXT: sete %cl ++; X87-CMOV-NEXT: andb %al, %cl ++; X87-CMOV-NEXT: testb $1, %cl + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -91,9 +104,11 @@ define i32 @test_f32_ogt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: seta %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmoval %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -108,9 +123,11 @@ define i32 @test_f32_ogt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: seta %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmoval %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -130,7 +147,9 @@ define i32 @test_f32_ogt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: ja .LBB1_1 ++; X87-NEXT: seta %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB1_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -147,9 +166,11 @@ define i32 @test_f32_ogt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: seta %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmoval %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -164,9 +185,11 @@ define i32 @test_f32_oge_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setae %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovael %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -181,9 +204,11 @@ define i32 @test_f32_oge_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setae %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovael %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -203,7 +228,9 @@ define i32 @test_f32_oge_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jae .LBB2_1 ++; X87-NEXT: setae %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB2_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -220,9 +247,11 @@ define i32 @test_f32_oge_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setae %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovael %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -237,9 +266,11 @@ define i32 @test_f32_olt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: seta %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmoval %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -254,9 +285,11 @@ define i32 @test_f32_olt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: seta %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmoval %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -276,7 +309,9 @@ define i32 @test_f32_olt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: ja .LBB3_1 ++; X87-NEXT: seta %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB3_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -293,9 +328,11 @@ define i32 @test_f32_olt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: seta %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmoval %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -310,9 +347,11 @@ define i32 @test_f32_ole_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setae %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovael %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -327,9 +366,11 @@ define i32 @test_f32_ole_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setae %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovael %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -349,7 +390,9 @@ define i32 @test_f32_ole_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jae .LBB4_1 ++; X87-NEXT: setae %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB4_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -366,9 +409,11 @@ define i32 @test_f32_ole_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setae %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovael %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -383,6 +428,8 @@ define i32 @test_f32_one_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setne %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +@@ -400,6 +447,8 @@ define i32 @test_f32_one_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setne %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +@@ -422,6 +471,8 @@ define i32 @test_f32_one_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf ++; X87-NEXT: setne %al ++; X87-NEXT: testb $1, %al + ; X87-NEXT: jne .LBB5_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +@@ -439,6 +490,8 @@ define i32 @test_f32_one_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setne %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +@@ -456,9 +509,11 @@ define i32 @test_f32_ord_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setnp %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovnpl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -473,9 +528,11 @@ define i32 @test_f32_ord_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setnp %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovnpl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -495,7 +552,9 @@ define i32 @test_f32_ord_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jnp .LBB6_1 ++; X87-NEXT: setnp %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB6_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -512,9 +571,11 @@ define i32 @test_f32_ord_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setnp %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovnpl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -529,9 +590,11 @@ define i32 @test_f32_ueq_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: sete %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -546,9 +609,11 @@ define i32 @test_f32_ueq_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: sete %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -568,7 +633,9 @@ define i32 @test_f32_ueq_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: je .LBB7_1 ++; X87-NEXT: sete %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB7_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -585,9 +652,11 @@ define i32 @test_f32_ueq_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: sete %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -602,9 +671,11 @@ define i32 @test_f32_ugt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setb %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -619,9 +690,11 @@ define i32 @test_f32_ugt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setb %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -641,7 +714,9 @@ define i32 @test_f32_ugt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jb .LBB8_1 ++; X87-NEXT: setb %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB8_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -658,9 +733,11 @@ define i32 @test_f32_ugt_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setb %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -675,9 +752,11 @@ define i32 @test_f32_uge_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setbe %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -692,9 +771,11 @@ define i32 @test_f32_uge_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setbe %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -714,7 +795,9 @@ define i32 @test_f32_uge_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jbe .LBB9_1 ++; X87-NEXT: setbe %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB9_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -731,9 +814,11 @@ define i32 @test_f32_uge_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setbe %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -748,9 +833,11 @@ define i32 @test_f32_ult_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setb %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -765,9 +852,11 @@ define i32 @test_f32_ult_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setb %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -787,7 +876,9 @@ define i32 @test_f32_ult_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jb .LBB10_1 ++; X87-NEXT: setb %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB10_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -804,9 +895,11 @@ define i32 @test_f32_ult_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setb %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -821,9 +914,11 @@ define i32 @test_f32_ule_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setbe %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -838,9 +933,11 @@ define i32 @test_f32_ule_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setbe %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -860,7 +957,9 @@ define i32 @test_f32_ule_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jbe .LBB11_1 ++; X87-NEXT: setbe %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB11_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -877,9 +976,11 @@ define i32 @test_f32_ule_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setbe %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -894,10 +995,13 @@ define i32 @test_f32_une_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setp %al ++; SSE-32-NEXT: setne %cl ++; SSE-32-NEXT: orb %al, %cl ++; SSE-32-NEXT: testb $1, %cl + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -913,10 +1017,13 @@ define i32 @test_f32_une_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setp %al ++; AVX-32-NEXT: setne %cl ++; AVX-32-NEXT: orb %al, %cl ++; AVX-32-NEXT: testb $1, %cl + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -937,13 +1044,17 @@ define i32 @test_f32_une_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: jne .LBB12_3 +-; X87-NEXT: # %bb.1: +-; X87-NEXT: jp .LBB12_3 ++; X87-NEXT: setp %al ++; X87-NEXT: setne %cl ++; X87-NEXT: orb %al, %cl ++; X87-NEXT: testb $1, %cl ++; X87-NEXT: jne .LBB12_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: .LBB12_3: ++; X87-NEXT: movl (%eax), %eax ++; X87-NEXT: retl ++; X87-NEXT: .LBB12_1: ++; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax + ; X87-NEXT: retl + ; +@@ -954,10 +1065,13 @@ define i32 @test_f32_une_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setp %al ++; X87-CMOV-NEXT: setne %cl ++; X87-CMOV-NEXT: orb %al, %cl ++; X87-CMOV-NEXT: testb $1, %cl + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -972,9 +1086,11 @@ define i32 @test_f32_uno_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setp %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -989,9 +1105,11 @@ define i32 @test_f32_uno_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setp %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1011,7 +1129,9 @@ define i32 @test_f32_uno_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jp .LBB13_1 ++; X87-NEXT: setp %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB13_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1028,9 +1148,11 @@ define i32 @test_f32_uno_q(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setp %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f32( +@@ -1045,10 +1167,13 @@ define i32 @test_f64_oeq_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setnp %al ++; SSE-32-NEXT: sete %cl ++; SSE-32-NEXT: andb %al, %cl ++; SSE-32-NEXT: testb $1, %cl + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1064,10 +1189,13 @@ define i32 @test_f64_oeq_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setnp %al ++; AVX-32-NEXT: sete %cl ++; AVX-32-NEXT: andb %al, %cl ++; AVX-32-NEXT: testb $1, %cl + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1088,13 +1216,17 @@ define i32 @test_f64_oeq_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: jne .LBB14_3 +-; X87-NEXT: # %bb.1: +-; X87-NEXT: jp .LBB14_3 ++; X87-NEXT: setnp %al ++; X87-NEXT: sete %cl ++; X87-NEXT: andb %al, %cl ++; X87-NEXT: testb $1, %cl ++; X87-NEXT: jne .LBB14_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: .LBB14_3: ++; X87-NEXT: movl (%eax), %eax ++; X87-NEXT: retl ++; X87-NEXT: .LBB14_1: ++; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax + ; X87-NEXT: retl + ; +@@ -1105,10 +1237,13 @@ define i32 @test_f64_oeq_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setnp %al ++; X87-CMOV-NEXT: sete %cl ++; X87-CMOV-NEXT: andb %al, %cl ++; X87-CMOV-NEXT: testb $1, %cl + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1123,9 +1258,11 @@ define i32 @test_f64_ogt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: seta %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmoval %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1140,9 +1277,11 @@ define i32 @test_f64_ogt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: seta %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmoval %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1162,7 +1301,9 @@ define i32 @test_f64_ogt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: ja .LBB15_1 ++; X87-NEXT: seta %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB15_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1179,9 +1320,11 @@ define i32 @test_f64_ogt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: seta %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmoval %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1196,9 +1339,11 @@ define i32 @test_f64_oge_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setae %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovael %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1213,9 +1358,11 @@ define i32 @test_f64_oge_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setae %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovael %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1235,7 +1382,9 @@ define i32 @test_f64_oge_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jae .LBB16_1 ++; X87-NEXT: setae %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB16_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1252,9 +1401,11 @@ define i32 @test_f64_oge_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setae %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovael %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1269,9 +1420,11 @@ define i32 @test_f64_olt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: seta %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmoval %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1286,9 +1439,11 @@ define i32 @test_f64_olt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: seta %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmoval %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1308,7 +1463,9 @@ define i32 @test_f64_olt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: ja .LBB17_1 ++; X87-NEXT: seta %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB17_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1325,9 +1482,11 @@ define i32 @test_f64_olt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: seta %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmoval %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1342,9 +1501,11 @@ define i32 @test_f64_ole_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setae %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovael %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1359,9 +1520,11 @@ define i32 @test_f64_ole_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setae %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovael %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1381,7 +1544,9 @@ define i32 @test_f64_ole_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jae .LBB18_1 ++; X87-NEXT: setae %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB18_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1398,9 +1563,11 @@ define i32 @test_f64_ole_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setae %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovael %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1415,6 +1582,8 @@ define i32 @test_f64_one_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setne %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +@@ -1432,6 +1601,8 @@ define i32 @test_f64_one_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setne %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +@@ -1454,6 +1625,8 @@ define i32 @test_f64_one_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf ++; X87-NEXT: setne %al ++; X87-NEXT: testb $1, %al + ; X87-NEXT: jne .LBB19_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +@@ -1471,6 +1644,8 @@ define i32 @test_f64_one_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setne %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +@@ -1488,9 +1663,11 @@ define i32 @test_f64_ord_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setnp %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovnpl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1505,9 +1682,11 @@ define i32 @test_f64_ord_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setnp %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovnpl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1527,7 +1706,9 @@ define i32 @test_f64_ord_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jnp .LBB20_1 ++; X87-NEXT: setnp %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB20_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1544,9 +1725,11 @@ define i32 @test_f64_ord_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setnp %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovnpl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1561,9 +1744,11 @@ define i32 @test_f64_ueq_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: sete %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1578,9 +1763,11 @@ define i32 @test_f64_ueq_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: sete %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1600,7 +1787,9 @@ define i32 @test_f64_ueq_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: je .LBB21_1 ++; X87-NEXT: sete %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB21_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1617,9 +1806,11 @@ define i32 @test_f64_ueq_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: sete %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1634,9 +1825,11 @@ define i32 @test_f64_ugt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setb %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1651,9 +1844,11 @@ define i32 @test_f64_ugt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setb %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1673,7 +1868,9 @@ define i32 @test_f64_ugt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jb .LBB22_1 ++; X87-NEXT: setb %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB22_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1690,9 +1887,11 @@ define i32 @test_f64_ugt_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setb %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1707,9 +1906,11 @@ define i32 @test_f64_uge_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setbe %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1724,9 +1925,11 @@ define i32 @test_f64_uge_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setbe %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1746,7 +1949,9 @@ define i32 @test_f64_uge_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jbe .LBB23_1 ++; X87-NEXT: setbe %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB23_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1763,9 +1968,11 @@ define i32 @test_f64_uge_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setbe %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1780,9 +1987,11 @@ define i32 @test_f64_ult_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setb %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1797,9 +2006,11 @@ define i32 @test_f64_ult_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setb %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1819,7 +2030,9 @@ define i32 @test_f64_ult_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jb .LBB24_1 ++; X87-NEXT: setb %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB24_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1836,9 +2049,11 @@ define i32 @test_f64_ult_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setb %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1853,9 +2068,11 @@ define i32 @test_f64_ule_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setbe %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1870,9 +2087,11 @@ define i32 @test_f64_ule_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setbe %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1892,7 +2111,9 @@ define i32 @test_f64_ule_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jbe .LBB25_1 ++; X87-NEXT: setbe %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB25_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -1909,9 +2130,11 @@ define i32 @test_f64_ule_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setbe %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -1926,10 +2149,13 @@ define i32 @test_f64_une_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setp %al ++; SSE-32-NEXT: setne %cl ++; SSE-32-NEXT: orb %al, %cl ++; SSE-32-NEXT: testb $1, %cl + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -1945,10 +2171,13 @@ define i32 @test_f64_une_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setp %al ++; AVX-32-NEXT: setne %cl ++; AVX-32-NEXT: orb %al, %cl ++; AVX-32-NEXT: testb $1, %cl + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -1969,13 +2198,17 @@ define i32 @test_f64_une_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: jne .LBB26_3 +-; X87-NEXT: # %bb.1: +-; X87-NEXT: jp .LBB26_3 ++; X87-NEXT: setp %al ++; X87-NEXT: setne %cl ++; X87-NEXT: orb %al, %cl ++; X87-NEXT: testb $1, %cl ++; X87-NEXT: jne .LBB26_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: .LBB26_3: ++; X87-NEXT: movl (%eax), %eax ++; X87-NEXT: retl ++; X87-NEXT: .LBB26_1: ++; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax + ; X87-NEXT: retl + ; +@@ -1986,10 +2219,13 @@ define i32 @test_f64_une_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setp %al ++; X87-CMOV-NEXT: setne %cl ++; X87-CMOV-NEXT: orb %al, %cl ++; X87-CMOV-NEXT: testb $1, %cl + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -2004,9 +2240,11 @@ define i32 @test_f64_uno_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: ucomisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setp %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2021,9 +2259,11 @@ define i32 @test_f64_uno_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vucomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setp %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2043,7 +2283,9 @@ define i32 @test_f64_uno_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jp .LBB27_1 ++; X87-NEXT: setp %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB27_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2060,9 +2302,11 @@ define i32 @test_f64_uno_q(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fucompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setp %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmp.f64( +@@ -2077,10 +2321,13 @@ define i32 @test_f32_oeq_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setnp %al ++; SSE-32-NEXT: sete %cl ++; SSE-32-NEXT: andb %al, %cl ++; SSE-32-NEXT: testb $1, %cl + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2096,10 +2343,13 @@ define i32 @test_f32_oeq_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setnp %al ++; AVX-32-NEXT: sete %cl ++; AVX-32-NEXT: andb %al, %cl ++; AVX-32-NEXT: testb $1, %cl + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2120,13 +2370,17 @@ define i32 @test_f32_oeq_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: jne .LBB28_3 +-; X87-NEXT: # %bb.1: +-; X87-NEXT: jp .LBB28_3 ++; X87-NEXT: setnp %al ++; X87-NEXT: sete %cl ++; X87-NEXT: andb %al, %cl ++; X87-NEXT: testb $1, %cl ++; X87-NEXT: jne .LBB28_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: .LBB28_3: ++; X87-NEXT: movl (%eax), %eax ++; X87-NEXT: retl ++; X87-NEXT: .LBB28_1: ++; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax + ; X87-NEXT: retl + ; +@@ -2137,10 +2391,13 @@ define i32 @test_f32_oeq_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setnp %al ++; X87-CMOV-NEXT: sete %cl ++; X87-CMOV-NEXT: andb %al, %cl ++; X87-CMOV-NEXT: testb $1, %cl + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2155,9 +2412,11 @@ define i32 @test_f32_ogt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: seta %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmoval %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2172,9 +2431,11 @@ define i32 @test_f32_ogt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: seta %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmoval %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2194,7 +2455,9 @@ define i32 @test_f32_ogt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: ja .LBB29_1 ++; X87-NEXT: seta %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB29_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2211,9 +2474,11 @@ define i32 @test_f32_ogt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: seta %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmoval %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2228,9 +2493,11 @@ define i32 @test_f32_oge_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setae %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovael %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2245,9 +2512,11 @@ define i32 @test_f32_oge_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setae %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovael %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2267,7 +2536,9 @@ define i32 @test_f32_oge_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jae .LBB30_1 ++; X87-NEXT: setae %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB30_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2284,9 +2555,11 @@ define i32 @test_f32_oge_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setae %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovael %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2301,9 +2574,11 @@ define i32 @test_f32_olt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: seta %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmoval %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2318,9 +2593,11 @@ define i32 @test_f32_olt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: seta %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmoval %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2340,7 +2617,9 @@ define i32 @test_f32_olt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: ja .LBB31_1 ++; X87-NEXT: seta %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB31_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2357,9 +2636,11 @@ define i32 @test_f32_olt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: seta %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmoval %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2374,9 +2655,11 @@ define i32 @test_f32_ole_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setae %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovael %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2391,9 +2674,11 @@ define i32 @test_f32_ole_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setae %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovael %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2413,7 +2698,9 @@ define i32 @test_f32_ole_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jae .LBB32_1 ++; X87-NEXT: setae %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB32_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2430,9 +2717,11 @@ define i32 @test_f32_ole_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setae %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovael %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2447,6 +2736,8 @@ define i32 @test_f32_one_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setne %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +@@ -2464,6 +2755,8 @@ define i32 @test_f32_one_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setne %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +@@ -2486,6 +2779,8 @@ define i32 @test_f32_one_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf ++; X87-NEXT: setne %al ++; X87-NEXT: testb $1, %al + ; X87-NEXT: jne .LBB33_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +@@ -2503,6 +2798,8 @@ define i32 @test_f32_one_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setne %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +@@ -2520,9 +2817,11 @@ define i32 @test_f32_ord_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setnp %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovnpl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2537,9 +2836,11 @@ define i32 @test_f32_ord_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setnp %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovnpl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2559,7 +2860,9 @@ define i32 @test_f32_ord_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jnp .LBB34_1 ++; X87-NEXT: setnp %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB34_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2576,9 +2879,11 @@ define i32 @test_f32_ord_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setnp %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovnpl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2593,9 +2898,11 @@ define i32 @test_f32_ueq_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: sete %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2610,9 +2917,11 @@ define i32 @test_f32_ueq_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: sete %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2632,7 +2941,9 @@ define i32 @test_f32_ueq_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: je .LBB35_1 ++; X87-NEXT: sete %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB35_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2649,9 +2960,11 @@ define i32 @test_f32_ueq_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: sete %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2666,9 +2979,11 @@ define i32 @test_f32_ugt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setb %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2683,9 +2998,11 @@ define i32 @test_f32_ugt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setb %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2705,7 +3022,9 @@ define i32 @test_f32_ugt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jb .LBB36_1 ++; X87-NEXT: setb %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB36_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2722,9 +3041,11 @@ define i32 @test_f32_ugt_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setb %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2739,9 +3060,11 @@ define i32 @test_f32_uge_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setbe %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2756,9 +3079,11 @@ define i32 @test_f32_uge_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setbe %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2778,7 +3103,9 @@ define i32 @test_f32_uge_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jbe .LBB37_1 ++; X87-NEXT: setbe %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB37_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2795,9 +3122,11 @@ define i32 @test_f32_uge_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setbe %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2812,9 +3141,11 @@ define i32 @test_f32_ult_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setb %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2829,9 +3160,11 @@ define i32 @test_f32_ult_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setb %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2851,7 +3184,9 @@ define i32 @test_f32_ult_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jb .LBB38_1 ++; X87-NEXT: setb %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB38_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2868,9 +3203,11 @@ define i32 @test_f32_ult_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setb %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2885,9 +3222,11 @@ define i32 @test_f32_ule_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setbe %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2902,9 +3241,11 @@ define i32 @test_f32_ule_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setbe %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -2924,7 +3265,9 @@ define i32 @test_f32_ule_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jbe .LBB39_1 ++; X87-NEXT: setbe %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB39_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -2941,9 +3284,11 @@ define i32 @test_f32_ule_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setbe %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -2958,10 +3303,13 @@ define i32 @test_f32_une_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setp %al ++; SSE-32-NEXT: setne %cl ++; SSE-32-NEXT: orb %al, %cl ++; SSE-32-NEXT: testb $1, %cl + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -2977,10 +3325,13 @@ define i32 @test_f32_une_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setp %al ++; AVX-32-NEXT: setne %cl ++; AVX-32-NEXT: orb %al, %cl ++; AVX-32-NEXT: testb $1, %cl + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3001,13 +3352,17 @@ define i32 @test_f32_une_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: jne .LBB40_3 +-; X87-NEXT: # %bb.1: +-; X87-NEXT: jp .LBB40_3 ++; X87-NEXT: setp %al ++; X87-NEXT: setne %cl ++; X87-NEXT: orb %al, %cl ++; X87-NEXT: testb $1, %cl ++; X87-NEXT: jne .LBB40_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: .LBB40_3: ++; X87-NEXT: movl (%eax), %eax ++; X87-NEXT: retl ++; X87-NEXT: .LBB40_1: ++; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax + ; X87-NEXT: retl + ; +@@ -3018,10 +3373,13 @@ define i32 @test_f32_une_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setp %al ++; X87-CMOV-NEXT: setne %cl ++; X87-CMOV-NEXT: orb %al, %cl ++; X87-CMOV-NEXT: testb $1, %cl + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -3036,9 +3394,11 @@ define i32 @test_f32_uno_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; SSE-32-NEXT: comiss {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setp %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3053,9 +3413,11 @@ define i32 @test_f32_uno_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero + ; AVX-32-NEXT: vcomiss {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setp %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3075,7 +3437,9 @@ define i32 @test_f32_uno_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jp .LBB41_1 ++; X87-NEXT: setp %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB41_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3092,9 +3456,11 @@ define i32 @test_f32_uno_s(i32 %a, i32 %b, float %f1, float %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setp %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f32( +@@ -3109,10 +3475,13 @@ define i32 @test_f64_oeq_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setnp %al ++; SSE-32-NEXT: sete %cl ++; SSE-32-NEXT: andb %al, %cl ++; SSE-32-NEXT: testb $1, %cl + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3128,10 +3497,13 @@ define i32 @test_f64_oeq_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setnp %al ++; AVX-32-NEXT: sete %cl ++; AVX-32-NEXT: andb %al, %cl ++; AVX-32-NEXT: testb $1, %cl + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3152,13 +3524,17 @@ define i32 @test_f64_oeq_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: jne .LBB42_3 +-; X87-NEXT: # %bb.1: +-; X87-NEXT: jp .LBB42_3 ++; X87-NEXT: setnp %al ++; X87-NEXT: sete %cl ++; X87-NEXT: andb %al, %cl ++; X87-NEXT: testb $1, %cl ++; X87-NEXT: jne .LBB42_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: .LBB42_3: ++; X87-NEXT: movl (%eax), %eax ++; X87-NEXT: retl ++; X87-NEXT: .LBB42_1: ++; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax + ; X87-NEXT: retl + ; +@@ -3169,10 +3545,13 @@ define i32 @test_f64_oeq_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setnp %al ++; X87-CMOV-NEXT: sete %cl ++; X87-CMOV-NEXT: andb %al, %cl ++; X87-CMOV-NEXT: testb $1, %cl + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3187,9 +3566,11 @@ define i32 @test_f64_ogt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: seta %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmoval %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3204,9 +3585,11 @@ define i32 @test_f64_ogt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: seta %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmoval %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3226,7 +3609,9 @@ define i32 @test_f64_ogt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: ja .LBB43_1 ++; X87-NEXT: seta %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB43_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3243,9 +3628,11 @@ define i32 @test_f64_ogt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: seta %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmoval %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3260,9 +3647,11 @@ define i32 @test_f64_oge_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setae %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovael %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3277,9 +3666,11 @@ define i32 @test_f64_oge_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setae %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovael %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3299,7 +3690,9 @@ define i32 @test_f64_oge_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jae .LBB44_1 ++; X87-NEXT: setae %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB44_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3316,9 +3709,11 @@ define i32 @test_f64_oge_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setae %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovael %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3333,9 +3728,11 @@ define i32 @test_f64_olt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: seta %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmoval %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3350,9 +3747,11 @@ define i32 @test_f64_olt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: seta %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmoval %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3372,7 +3771,9 @@ define i32 @test_f64_olt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: ja .LBB45_1 ++; X87-NEXT: seta %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB45_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3389,9 +3790,11 @@ define i32 @test_f64_olt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: seta %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmoval %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3406,9 +3809,11 @@ define i32 @test_f64_ole_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setae %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovael %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3423,9 +3828,11 @@ define i32 @test_f64_ole_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setae %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovael %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3445,7 +3852,9 @@ define i32 @test_f64_ole_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jae .LBB46_1 ++; X87-NEXT: setae %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB46_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3462,9 +3871,11 @@ define i32 @test_f64_ole_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setae %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovael %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3479,6 +3890,8 @@ define i32 @test_f64_one_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setne %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +@@ -3496,6 +3909,8 @@ define i32 @test_f64_one_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setne %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +@@ -3518,6 +3933,8 @@ define i32 @test_f64_one_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf ++; X87-NEXT: setne %al ++; X87-NEXT: testb $1, %al + ; X87-NEXT: jne .LBB47_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +@@ -3535,6 +3952,8 @@ define i32 @test_f64_one_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setne %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +@@ -3552,9 +3971,11 @@ define i32 @test_f64_ord_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setnp %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovnpl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3569,9 +3990,11 @@ define i32 @test_f64_ord_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setnp %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovnpl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3591,7 +4014,9 @@ define i32 @test_f64_ord_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jnp .LBB48_1 ++; X87-NEXT: setnp %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB48_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3608,9 +4033,11 @@ define i32 @test_f64_ord_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setnp %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovnpl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3625,9 +4052,11 @@ define i32 @test_f64_ueq_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: sete %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3642,9 +4071,11 @@ define i32 @test_f64_ueq_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: sete %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3664,7 +4095,9 @@ define i32 @test_f64_ueq_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: je .LBB49_1 ++; X87-NEXT: sete %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB49_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3681,9 +4114,11 @@ define i32 @test_f64_ueq_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: sete %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3698,9 +4133,11 @@ define i32 @test_f64_ugt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setb %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3715,9 +4152,11 @@ define i32 @test_f64_ugt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setb %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3737,7 +4176,9 @@ define i32 @test_f64_ugt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jb .LBB50_1 ++; X87-NEXT: setb %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB50_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3754,9 +4195,11 @@ define i32 @test_f64_ugt_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setb %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3771,9 +4214,11 @@ define i32 @test_f64_uge_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setbe %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3788,9 +4233,11 @@ define i32 @test_f64_uge_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setbe %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3810,7 +4257,9 @@ define i32 @test_f64_uge_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jbe .LBB51_1 ++; X87-NEXT: setbe %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB51_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3827,9 +4276,11 @@ define i32 @test_f64_uge_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setbe %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3844,9 +4295,11 @@ define i32 @test_f64_ult_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setb %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3861,9 +4314,11 @@ define i32 @test_f64_ult_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setb %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3883,7 +4338,9 @@ define i32 @test_f64_ult_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jb .LBB52_1 ++; X87-NEXT: setb %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB52_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3900,9 +4357,11 @@ define i32 @test_f64_ult_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setb %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3917,9 +4376,11 @@ define i32 @test_f64_ule_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setbe %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovbel %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -3934,9 +4395,11 @@ define i32 @test_f64_ule_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setbe %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovbel %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -3956,7 +4419,9 @@ define i32 @test_f64_ule_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jbe .LBB53_1 ++; X87-NEXT: setbe %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB53_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -3973,9 +4438,11 @@ define i32 @test_f64_ule_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setbe %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovbel %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -3990,10 +4457,13 @@ define i32 @test_f64_une_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setp %al ++; SSE-32-NEXT: setne %cl ++; SSE-32-NEXT: orb %al, %cl ++; SSE-32-NEXT: testb $1, %cl + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SSE-32-NEXT: cmovnel %eax, %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -4009,10 +4479,13 @@ define i32 @test_f64_une_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setp %al ++; AVX-32-NEXT: setne %cl ++; AVX-32-NEXT: orb %al, %cl ++; AVX-32-NEXT: testb $1, %cl + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; AVX-32-NEXT: cmovnel %eax, %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -4033,13 +4506,17 @@ define i32 @test_f64_une_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: jne .LBB54_3 +-; X87-NEXT: # %bb.1: +-; X87-NEXT: jp .LBB54_3 ++; X87-NEXT: setp %al ++; X87-NEXT: setne %cl ++; X87-NEXT: orb %al, %cl ++; X87-NEXT: testb $1, %cl ++; X87-NEXT: jne .LBB54_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X87-NEXT: .LBB54_3: ++; X87-NEXT: movl (%eax), %eax ++; X87-NEXT: retl ++; X87-NEXT: .LBB54_1: ++; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax + ; X87-NEXT: retl + ; +@@ -4050,10 +4527,13 @@ define i32 @test_f64_une_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setp %al ++; X87-CMOV-NEXT: setne %cl ++; X87-CMOV-NEXT: orb %al, %cl ++; X87-CMOV-NEXT: testb $1, %cl + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X87-CMOV-NEXT: cmovnel %eax, %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +@@ -4068,9 +4548,11 @@ define i32 @test_f64_uno_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; SSE-32: # %bb.0: + ; SSE-32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero + ; SSE-32-NEXT: comisd {{[0-9]+}}(%esp), %xmm0 ++; SSE-32-NEXT: setp %al ++; SSE-32-NEXT: testb $1, %al + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SSE-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; SSE-32-NEXT: cmovpl %eax, %ecx ++; SSE-32-NEXT: cmovnel %eax, %ecx + ; SSE-32-NEXT: movl (%ecx), %eax + ; SSE-32-NEXT: retl + ; +@@ -4085,9 +4567,11 @@ define i32 @test_f64_uno_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; AVX-32: # %bb.0: + ; AVX-32-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero + ; AVX-32-NEXT: vcomisd {{[0-9]+}}(%esp), %xmm0 ++; AVX-32-NEXT: setp %al ++; AVX-32-NEXT: testb $1, %al + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %eax + ; AVX-32-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; AVX-32-NEXT: cmovpl %eax, %ecx ++; AVX-32-NEXT: cmovnel %eax, %ecx + ; AVX-32-NEXT: movl (%ecx), %eax + ; AVX-32-NEXT: retl + ; +@@ -4107,7 +4591,9 @@ define i32 @test_f64_uno_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-NEXT: fnstsw %ax + ; X87-NEXT: # kill: def $ah killed $ah killed $ax + ; X87-NEXT: sahf +-; X87-NEXT: jp .LBB55_1 ++; X87-NEXT: setp %al ++; X87-NEXT: testb $1, %al ++; X87-NEXT: jne .LBB55_1 + ; X87-NEXT: # %bb.2: + ; X87-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-NEXT: movl (%eax), %eax +@@ -4124,9 +4610,11 @@ define i32 @test_f64_uno_s(i32 %a, i32 %b, double %f1, double %f2) #0 { + ; X87-CMOV-NEXT: fcompi %st(1), %st + ; X87-CMOV-NEXT: fstp %st(0) + ; X87-CMOV-NEXT: wait ++; X87-CMOV-NEXT: setp %al ++; X87-CMOV-NEXT: testb $1, %al + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X87-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx +-; X87-CMOV-NEXT: cmovpl %eax, %ecx ++; X87-CMOV-NEXT: cmovnel %eax, %ecx + ; X87-CMOV-NEXT: movl (%ecx), %eax + ; X87-CMOV-NEXT: retl + %cond = call i1 @llvm.experimental.constrained.fcmps.f64( +diff --git a/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll b/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll +index ad2d690fd7ed0..5dbc28230d5af 100644 +--- a/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll ++++ b/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll +@@ -3898,6 +3898,7 @@ define i64 @cmp_ueq_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 { + ; X86-NEXT: calll __unordtf2 + ; X86-NEXT: addl $32, %esp + ; X86-NEXT: orb %bl, %al ++; X86-NEXT: testb $1, %al + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; X86-NEXT: cmovnel %eax, %ecx +@@ -3981,6 +3982,7 @@ define i64 @cmp_ueq_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 { + ; WIN-X86-NEXT: calll ___unordtf2 + ; WIN-X86-NEXT: addl $32, %esp + ; WIN-X86-NEXT: orb %bl, %al ++; WIN-X86-NEXT: testb $1, %al + ; WIN-X86-NEXT: jne LBB39_1 + ; WIN-X86-NEXT: # %bb.2: + ; WIN-X86-NEXT: leal 16(%ebp), %ecx +diff --git a/llvm/test/CodeGen/X86/fp80-strict-scalar-cmp.ll b/llvm/test/CodeGen/X86/fp80-strict-scalar-cmp.ll +index cb2361fbb8d37..f95738d9e546e 100644 +--- a/llvm/test/CodeGen/X86/fp80-strict-scalar-cmp.ll ++++ b/llvm/test/CodeGen/X86/fp80-strict-scalar-cmp.ll +@@ -12,13 +12,17 @@ define i32 @test_oeq_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X86-NEXT: jne .LBB0_3 +-; X86-NEXT: # %bb.1: +-; X86-NEXT: jp .LBB0_3 ++; X86-NEXT: setnp %al ++; X86-NEXT: sete %cl ++; X86-NEXT: andb %al, %cl ++; X86-NEXT: testb $1, %cl ++; X86-NEXT: jne .LBB0_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X86-NEXT: .LBB0_3: ++; X86-NEXT: movl (%eax), %eax ++; X86-NEXT: retl ++; X86-NEXT: .LBB0_1: ++; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax + ; X86-NEXT: retl + ; +@@ -50,7 +54,9 @@ define i32 @test_ogt_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: ja .LBB1_1 ++; X86-NEXT: seta %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB1_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -87,7 +93,9 @@ define i32 @test_oge_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jae .LBB2_1 ++; X86-NEXT: setae %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB2_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -124,7 +132,9 @@ define i32 @test_olt_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: ja .LBB3_1 ++; X86-NEXT: seta %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB3_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -161,7 +171,9 @@ define i32 @test_ole_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jae .LBB4_1 ++; X86-NEXT: setae %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB4_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -198,6 +210,8 @@ define i32 @test_one_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf ++; X86-NEXT: setne %al ++; X86-NEXT: testb $1, %al + ; X86-NEXT: jne .LBB5_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +@@ -235,7 +249,9 @@ define i32 @test_ord_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jnp .LBB6_1 ++; X86-NEXT: setnp %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB6_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -272,7 +288,9 @@ define i32 @test_ueq_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: je .LBB7_1 ++; X86-NEXT: sete %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB7_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -309,7 +327,9 @@ define i32 @test_ugt_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jb .LBB8_1 ++; X86-NEXT: setb %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB8_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -346,7 +366,9 @@ define i32 @test_uge_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jbe .LBB9_1 ++; X86-NEXT: setbe %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB9_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -383,7 +405,9 @@ define i32 @test_ult_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jb .LBB10_1 ++; X86-NEXT: setb %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB10_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -420,7 +444,9 @@ define i32 @test_ule_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jbe .LBB11_1 ++; X86-NEXT: setbe %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB11_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -457,13 +483,17 @@ define i32 @test_une_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X86-NEXT: jne .LBB12_3 +-; X86-NEXT: # %bb.1: +-; X86-NEXT: jp .LBB12_3 ++; X86-NEXT: setp %al ++; X86-NEXT: setne %cl ++; X86-NEXT: orb %al, %cl ++; X86-NEXT: testb $1, %cl ++; X86-NEXT: jne .LBB12_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X86-NEXT: .LBB12_3: ++; X86-NEXT: movl (%eax), %eax ++; X86-NEXT: retl ++; X86-NEXT: .LBB12_1: ++; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax + ; X86-NEXT: retl + ; +@@ -495,7 +525,9 @@ define i32 @test_uno_q(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jp .LBB13_1 ++; X86-NEXT: setp %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB13_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -532,13 +564,17 @@ define i32 @test_oeq_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X86-NEXT: jne .LBB14_3 +-; X86-NEXT: # %bb.1: +-; X86-NEXT: jp .LBB14_3 ++; X86-NEXT: setnp %al ++; X86-NEXT: sete %cl ++; X86-NEXT: andb %al, %cl ++; X86-NEXT: testb $1, %cl ++; X86-NEXT: jne .LBB14_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X86-NEXT: .LBB14_3: ++; X86-NEXT: movl (%eax), %eax ++; X86-NEXT: retl ++; X86-NEXT: .LBB14_1: ++; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax + ; X86-NEXT: retl + ; +@@ -570,7 +606,9 @@ define i32 @test_ogt_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: ja .LBB15_1 ++; X86-NEXT: seta %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB15_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -607,7 +645,9 @@ define i32 @test_oge_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jae .LBB16_1 ++; X86-NEXT: setae %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB16_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -644,7 +684,9 @@ define i32 @test_olt_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: ja .LBB17_1 ++; X86-NEXT: seta %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB17_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -681,7 +723,9 @@ define i32 @test_ole_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jae .LBB18_1 ++; X86-NEXT: setae %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB18_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -718,6 +762,8 @@ define i32 @test_one_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf ++; X86-NEXT: setne %al ++; X86-NEXT: testb $1, %al + ; X86-NEXT: jne .LBB19_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +@@ -755,7 +801,9 @@ define i32 @test_ord_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jnp .LBB20_1 ++; X86-NEXT: setnp %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB20_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -792,7 +840,9 @@ define i32 @test_ueq_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: je .LBB21_1 ++; X86-NEXT: sete %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB21_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -829,7 +879,9 @@ define i32 @test_ugt_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jb .LBB22_1 ++; X86-NEXT: setb %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB22_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -866,7 +918,9 @@ define i32 @test_uge_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jbe .LBB23_1 ++; X86-NEXT: setbe %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB23_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -903,7 +957,9 @@ define i32 @test_ult_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jb .LBB24_1 ++; X86-NEXT: setb %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB24_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -940,7 +996,9 @@ define i32 @test_ule_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jbe .LBB25_1 ++; X86-NEXT: setbe %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB25_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -977,13 +1035,17 @@ define i32 @test_une_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X86-NEXT: jne .LBB26_3 +-; X86-NEXT: # %bb.1: +-; X86-NEXT: jp .LBB26_3 ++; X86-NEXT: setp %al ++; X86-NEXT: setne %cl ++; X86-NEXT: orb %al, %cl ++; X86-NEXT: testb $1, %cl ++; X86-NEXT: jne .LBB26_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax +-; X86-NEXT: .LBB26_3: ++; X86-NEXT: movl (%eax), %eax ++; X86-NEXT: retl ++; X86-NEXT: .LBB26_1: ++; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax + ; X86-NEXT: retl + ; +@@ -1015,7 +1077,9 @@ define i32 @test_uno_s(i32 %a, i32 %b, x86_fp80 %f1, x86_fp80 %f2) #0 { + ; X86-NEXT: fnstsw %ax + ; X86-NEXT: # kill: def $ah killed $ah killed $ax + ; X86-NEXT: sahf +-; X86-NEXT: jp .LBB27_1 ++; X86-NEXT: setp %al ++; X86-NEXT: testb $1, %al ++; X86-NEXT: jne .LBB27_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +diff --git a/llvm/test/CodeGen/X86/isel-select-cmov.ll b/llvm/test/CodeGen/X86/isel-select-cmov.ll +index d013ad2c7fbff..6ced7f45b6233 100644 +--- a/llvm/test/CodeGen/X86/isel-select-cmov.ll ++++ b/llvm/test/CodeGen/X86/isel-select-cmov.ll +@@ -47,7 +47,7 @@ define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b + ; + ; SDAG-X86-LABEL: select_cmov_i8: + ; SDAG-X86: ## %bb.0: +-; SDAG-X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) ++; SDAG-X86-NEXT: testb $1, {{[0-9]+}}(%esp) + ; SDAG-X86-NEXT: jne LBB0_1 + ; SDAG-X86-NEXT: ## %bb.2: + ; SDAG-X86-NEXT: leal {{[0-9]+}}(%esp), %eax +@@ -60,7 +60,7 @@ define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b + ; + ; SDAG-X86-CMOV-LABEL: select_cmov_i8: + ; SDAG-X86-CMOV: ## %bb.0: +-; SDAG-X86-CMOV-NEXT: cmpb $0, {{[0-9]+}}(%esp) ++; SDAG-X86-CMOV-NEXT: testb $1, {{[0-9]+}}(%esp) + ; SDAG-X86-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SDAG-X86-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SDAG-X86-CMOV-NEXT: cmovnel %eax, %ecx +@@ -155,7 +155,7 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex + ; + ; SDAG-X86-LABEL: select_cmov_i16: + ; SDAG-X86: ## %bb.0: +-; SDAG-X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) ++; SDAG-X86-NEXT: testb $1, {{[0-9]+}}(%esp) + ; SDAG-X86-NEXT: jne LBB1_1 + ; SDAG-X86-NEXT: ## %bb.2: + ; SDAG-X86-NEXT: leal {{[0-9]+}}(%esp), %eax +@@ -168,7 +168,7 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex + ; + ; SDAG-X86-CMOV-LABEL: select_cmov_i16: + ; SDAG-X86-CMOV: ## %bb.0: +-; SDAG-X86-CMOV-NEXT: cmpb $0, {{[0-9]+}}(%esp) ++; SDAG-X86-CMOV-NEXT: testb $1, {{[0-9]+}}(%esp) + ; SDAG-X86-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SDAG-X86-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SDAG-X86-CMOV-NEXT: cmovnel %eax, %ecx +@@ -360,7 +360,7 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) { + ; + ; SDAG-X86-LABEL: select_cmov_i32: + ; SDAG-X86: ## %bb.0: +-; SDAG-X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) ++; SDAG-X86-NEXT: testb $1, {{[0-9]+}}(%esp) + ; SDAG-X86-NEXT: jne LBB3_1 + ; SDAG-X86-NEXT: ## %bb.2: + ; SDAG-X86-NEXT: leal {{[0-9]+}}(%esp), %eax +@@ -373,7 +373,7 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) { + ; + ; SDAG-X86-CMOV-LABEL: select_cmov_i32: + ; SDAG-X86-CMOV: ## %bb.0: +-; SDAG-X86-CMOV-NEXT: cmpb $0, {{[0-9]+}}(%esp) ++; SDAG-X86-CMOV-NEXT: testb $1, {{[0-9]+}}(%esp) + ; SDAG-X86-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SDAG-X86-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SDAG-X86-CMOV-NEXT: cmovnel %eax, %ecx +@@ -549,7 +549,7 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) { + ; + ; SDAG-X86-LABEL: select_cmov_i64: + ; SDAG-X86: ## %bb.0: +-; SDAG-X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) ++; SDAG-X86-NEXT: testb $1, {{[0-9]+}}(%esp) + ; SDAG-X86-NEXT: jne LBB5_1 + ; SDAG-X86-NEXT: ## %bb.2: + ; SDAG-X86-NEXT: leal {{[0-9]+}}(%esp), %ecx +@@ -563,7 +563,7 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) { + ; + ; SDAG-X86-CMOV-LABEL: select_cmov_i64: + ; SDAG-X86-CMOV: ## %bb.0: +-; SDAG-X86-CMOV-NEXT: cmpb $0, {{[0-9]+}}(%esp) ++; SDAG-X86-CMOV-NEXT: testb $1, {{[0-9]+}}(%esp) + ; SDAG-X86-CMOV-NEXT: leal {{[0-9]+}}(%esp), %eax + ; SDAG-X86-CMOV-NEXT: leal {{[0-9]+}}(%esp), %ecx + ; SDAG-X86-CMOV-NEXT: cmovnel %eax, %ecx +diff --git a/llvm/test/CodeGen/X86/select-constant-xor.ll b/llvm/test/CodeGen/X86/select-constant-xor.ll +index efc367d204cf1..5d80e04fef38c 100644 +--- a/llvm/test/CodeGen/X86/select-constant-xor.ll ++++ b/llvm/test/CodeGen/X86/select-constant-xor.ll +@@ -172,8 +172,10 @@ define i32 @selecti8i32(i8 %a) { + define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) { + ; X86-LABEL: icmpasreq: + ; X86: # %bb.0: +-; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp) +-; X86-NEXT: js .LBB8_1 ++; X86-NEXT: movl {{[0-9]+}}(%esp), %eax ++; X86-NEXT: sarl $31, %eax ++; X86-NEXT: cmpl $-1, %eax ++; X86-NEXT: je .LBB8_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +@@ -198,8 +200,10 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) { + define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) { + ; X86-LABEL: icmpasrne: + ; X86: # %bb.0: +-; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp) +-; X86-NEXT: jns .LBB9_1 ++; X86-NEXT: movl {{[0-9]+}}(%esp), %eax ++; X86-NEXT: sarl $31, %eax ++; X86-NEXT: cmpl $-1, %eax ++; X86-NEXT: jne .LBB9_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax + ; X86-NEXT: movl (%eax), %eax +diff --git a/llvm/test/CodeGen/X86/select-mmx.ll b/llvm/test/CodeGen/X86/select-mmx.ll +index 8a4308a5af64b..cc6603382082c 100644 +--- a/llvm/test/CodeGen/X86/select-mmx.ll ++++ b/llvm/test/CodeGen/X86/select-mmx.ll +@@ -85,8 +85,8 @@ define i64 @test49(i64 %arg, i64 %x, i64 %y) { + ; X86-NEXT: .cfi_def_cfa_register %ebp + ; X86-NEXT: andl $-8, %esp + ; X86-NEXT: subl $8, %esp +-; X86-NEXT: movl 8(%ebp), %eax +-; X86-NEXT: orl 12(%ebp), %eax ++; X86-NEXT: movl 12(%ebp), %eax ++; X86-NEXT: orl 8(%ebp), %eax + ; X86-NEXT: je .LBB1_1 + ; X86-NEXT: # %bb.2: + ; X86-NEXT: leal 24(%ebp), %eax +diff --git a/llvm/test/CodeGen/X86/select-of-load-poison.ll b/llvm/test/CodeGen/X86/select-of-load-poison.ll +new file mode 100644 +index 0000000000000..1f71f812d2327 +--- /dev/null ++++ b/llvm/test/CodeGen/X86/select-of-load-poison.ll +@@ -0,0 +1,20 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 ++; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s ++ ++; Make sure there is an and 1, otherwise a case where the select condition ++; was poison could result in an out of bounds read instead. ++define i32 @test(i32 %x, ptr %p) { ++; CHECK-LABEL: test: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # kill: def $edi killed $edi def $rdi ++; CHECK-NEXT: andl $1, %edi ++; CHECK-NEXT: movl 4(%rsi,%rdi,4), %eax ++; CHECK-NEXT: retq ++ %p1 = getelementptr i8, ptr %p, i64 4 ++ %v1 = load i32, ptr %p1 ++ %p2 = getelementptr i8, ptr %p, i64 8 ++ %v2 = load i32, ptr %p2 ++ %c = trunc nuw i32 %x to i1 ++ %v = select i1 %c, i32 %v2, i32 %v1 ++ ret i32 %v ++} diff --git a/SOURCES/0001-SystemZ-Avoid-unaligned-VL-VST-s-with-memcpy-memmove.patch b/SOURCES/0001-SystemZ-Avoid-unaligned-VL-VST-s-with-memcpy-memmove.patch new file mode 100644 index 0000000..95a7dfb --- /dev/null +++ b/SOURCES/0001-SystemZ-Avoid-unaligned-VL-VST-s-with-memcpy-memmove.patch @@ -0,0 +1,4156 @@ +From deb79107cdc640de8ccf4512a01512e7a8dcb72e Mon Sep 17 00:00:00 2001 +From: Jonas Paulsson +Date: Tue, 28 Apr 2026 19:09:09 +0200 +Subject: [PATCH] [SystemZ] Avoid unaligned VL/VST:s with + memcpy/memmove/memset. (#187100) + +This is a squash of the proposed backport PR #196359 and its dependencies +to llvm 22: + +[SystemZ] Improved testing for memcpy/memmove/memset. (#194682) +[SystemZ] Avoid unaligned VL/VST:s with memcpy/memmove/memset. (#187100) +[SystemZ] Remove superfluous args in tests. (#196022) +Fix memmove-01.ll test (to use libcalls in some cases). +--- + .../Target/SystemZ/SystemZISelLowering.cpp | 26 +- + llvm/test/CodeGen/SystemZ/memcpy-03.ll | 648 +++++- + llvm/test/CodeGen/SystemZ/memmove-01.ll | 1090 +++++++++ + llvm/test/CodeGen/SystemZ/memset-08.ll | 2018 +++++++++++++++-- + 4 files changed, 3453 insertions(+), 329 deletions(-) + create mode 100644 llvm/test/CodeGen/SystemZ/memmove-01.ll + +diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +index c3ded986fd68..78862759c880 100644 +--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp ++++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +@@ -830,6 +830,10 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM, + MaxStoresPerMemcpy = Subtarget.hasVector() ? 2 : 0; + MaxStoresPerMemcpyOptSize = 0; + ++ // Same with memmove. ++ MaxStoresPerMemmove = Subtarget.hasVector() ? 2 : 0; ++ MaxStoresPerMemmoveOptSize = 0; ++ + // The main memset sequence is a byte store followed by an MVC. + // Two STC or MV..I stores win over that, but the kind of fused stores + // generated by target-independent code don't when the byte value is +@@ -1473,17 +1477,21 @@ bool SystemZTargetLowering::findOptimalMemOpLowering( + LLVMContext &Context, std::vector &MemOps, unsigned Limit, + const MemOp &Op, unsigned DstAS, unsigned SrcAS, + const AttributeList &FuncAttributes) const { ++ ++ assert(Limit != ~0U && ++ "Expected EmitTargetCodeForMemXXX() to handle AlwaysInline cases."); ++ ++ if (Op.isZeroMemset()) ++ return false; // Memset zero: Use XC. ++ + const int MVCFastLen = 16; ++ // Use MVC up to 16 bytes. Small memset uses STC/MVI for first byte. ++ if ((Op.isMemset() ? Op.size() - 1 : Op.size()) <= MVCFastLen) ++ return false; + +- if (Limit != ~unsigned(0)) { +- // Don't expand Op into scalar loads/stores in these cases: +- if (Op.isMemcpy() && Op.allowOverlap() && Op.size() <= MVCFastLen) +- return false; // Small memcpy: Use MVC +- if (Op.isMemset() && Op.size() - 1 <= MVCFastLen) +- return false; // Small memset (first byte with STC/MVI): Use MVC +- if (Op.isZeroMemset()) +- return false; // Memset zero: Use XC +- } ++ // Avoid unaligned VL/VST:s. ++ if (!Op.isAligned(Align(8)) || (Op.size() >= 25 && Op.size() <= 31)) ++ return false; + + return TargetLowering::findOptimalMemOpLowering(Context, MemOps, Limit, Op, + DstAS, SrcAS, FuncAttributes); +diff --git a/llvm/test/CodeGen/SystemZ/memcpy-03.ll b/llvm/test/CodeGen/SystemZ/memcpy-03.ll +index c703aef27532..213764e79ffb 100644 +--- a/llvm/test/CodeGen/SystemZ/memcpy-03.ll ++++ b/llvm/test/CodeGen/SystemZ/memcpy-03.ll +@@ -1,217 +1,661 @@ + ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc -mcpu=z15 < %s -mtriple=s390x-linux-gnu | FileCheck %s ++; RUN: llc -mcpu=z17 < %s -mtriple=s390x-linux-gnu | FileCheck %s + ; +-; Test memcpys of small constant lengths that should not be done with MVC. ++; Test non-volatile memcpys of small constant lengths in both aligned and ++; unaligned cases. + + declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind + +-define void @fun16(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun1(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun1: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(1,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 1, i1 false) ++ ret void ++} ++ ++define void @fun1_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun1_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(1,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 1, i1 false) ++ ret void ++} ++ ++define void @fun2(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun2: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(2,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 2, i1 false) ++ ret void ++} ++ ++define void @fun2_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun2_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(2,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 2, i1 false) ++ ret void ++} ++ ++define void @fun3(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun3: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(3,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 3, i1 false) ++ ret void ++} ++ ++define void @fun3_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun3_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(3,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 3, i1 false) ++ ret void ++} ++ ++define void @fun4(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun4: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(4,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 4, i1 false) ++ ret void ++} ++ ++define void @fun4_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun4_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(4,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 4, i1 false) ++ ret void ++} ++ ++define void @fun5(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun5: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(5,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 5, i1 false) ++ ret void ++} ++ ++define void @fun5_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun5_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(5,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 5, i1 false) ++ ret void ++} ++ ++define void @fun6(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun6: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(6,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 6, i1 false) ++ ret void ++} ++ ++define void @fun6_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun6_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(6,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 6, i1 false) ++ ret void ++} ++ ++define void @fun7(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun7: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(7,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 7, i1 false) ++ ret void ++} ++ ++define void @fun7_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun7_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(7,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 7, i1 false) ++ ret void ++} ++ ++define void @fun8(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(8,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 8, i1 false) ++ ret void ++} ++ ++define void @fun8_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun8_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(8,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 8, i1 false) ++ ret void ++} ++ ++define void @fun9(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun9: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(9,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 9, i1 false) ++ ret void ++} ++ ++define void @fun9_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun9_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(9,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 9, i1 false) ++ ret void ++} ++ ++define void @fun10(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun10: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(10,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 10, i1 false) ++ ret void ++} ++ ++define void @fun10_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun10_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(10,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 10, i1 false) ++ ret void ++} ++ ++define void @fun11(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun11: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(11,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 11, i1 false) ++ ret void ++} ++ ++define void @fun11_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun11_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(11,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 11, i1 false) ++ ret void ++} ++ ++define void @fun12(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun12: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(12,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 12, i1 false) ++ ret void ++} ++ ++define void @fun12_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun12_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(12,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 12, i1 false) ++ ret void ++} ++ ++define void @fun13(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun13: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(13,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 13, i1 false) ++ ret void ++} ++ ++define void @fun13_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun13_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(13,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 13, i1 false) ++ ret void ++} ++ ++define void @fun14(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun14: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(14,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 14, i1 false) ++ ret void ++} ++ ++define void @fun14_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun14_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(14,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 14, i1 false) ++ ret void ++} ++ ++define void @fun15(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun15: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(15,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 15, i1 false) ++ ret void ++} ++ ++define void @fun15_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun15_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(15,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 15, i1 false) ++ ret void ++} ++ ++define void @fun16(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun16: + ; CHECK: # %bb.0: +-; CHECK-NEXT: mvc 0(16,%r3), 0(%r2) ++; CHECK-NEXT: mvc 0(16,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 16, i1 false) ++ ret void ++} ++ ++define void @fun16_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun16_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(16,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 16, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 16, i1 false) + ret void + } + +-define void @fun17(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun17(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun17: + ; CHECK: # %bb.0: +-; CHECK-NEXT: lb %r0, 16(%r2) +-; CHECK-NEXT: stc %r0, 16(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: lb %r0, 16(%r3) ++; CHECK-NEXT: stc %r0, 16(%r2) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 17, i1 false) ++ ret void ++} ++ ++define void @fun17_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun17_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(17,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 17, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 17, i1 false) + ret void + } + +-define void @fun18(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun17_unalignedSrc(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun17_unalignedSrc: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(17,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 4 %Src, i64 17, i1 false) ++ ret void ++} ++ ++define void @fun18(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun18: + ; CHECK: # %bb.0: +-; CHECK-NEXT: lh %r0, 16(%r2) +-; CHECK-NEXT: sth %r0, 16(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: lh %r0, 16(%r3) ++; CHECK-NEXT: sth %r0, 16(%r2) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 18, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 18, i1 false) + ret void + } + +-define void @fun19(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun18_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun18_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(18,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 18, i1 false) ++ ret void ++} ++ ++define void @fun18_unalignedDst(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun18_unalignedDst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(18,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 2 %Dst, ptr align 16 %Src, i64 18, i1 false) ++ ret void ++} ++ ++define void @fun19(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun19: + ; CHECK: # %bb.0: +-; CHECK-NEXT: l %r0, 15(%r2) +-; CHECK-NEXT: st %r0, 15(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: l %r0, 15(%r3) ++; CHECK-NEXT: st %r0, 15(%r2) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 19, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 19, i1 false) + ret void + } + +-define void @fun20(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun19_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun19_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(19,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 19, i1 false) ++ ret void ++} ++ ++define void @fun20(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun20: + ; CHECK: # %bb.0: +-; CHECK-NEXT: l %r0, 16(%r2) +-; CHECK-NEXT: st %r0, 16(%r3) ++; CHECK-NEXT: l %r0, 16(%r3) ++; CHECK-NEXT: st %r0, 16(%r2) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 20, i1 false) ++ ret void ++} ++ ++define void @fun20_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun20_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(20,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 20, i1 false) ++ ret void ++} ++ ++define void @fun20_localDst(ptr %Src) { ++; CHECK-LABEL: fun20_localDst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: aghi %r15, -184 ++; CHECK-NEXT: .cfi_def_cfa_offset 344 + ; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: vst %v0, 164(%r15), 4 ++; CHECK-NEXT: mvc 180(4,%r15), 16(%r2) ++; CHECK-NEXT: aghi %r15, 184 + ; CHECK-NEXT: br %r14 ++ %Dst = alloca [20 x i8] + call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 20, i1 false) + ret void + } + +-define void @fun21(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun21(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun21: + ; CHECK: # %bb.0: +-; CHECK-NEXT: lg %r0, 13(%r2) +-; CHECK-NEXT: stg %r0, 13(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: lg %r0, 13(%r3) ++; CHECK-NEXT: stg %r0, 13(%r2) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 21, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 21, i1 false) + ret void + } + +-define void @fun22(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun21_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun21_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(21,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 21, i1 false) ++ ret void ++} ++ ++define void @fun22(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun22: + ; CHECK: # %bb.0: +-; CHECK-NEXT: lg %r0, 14(%r2) +-; CHECK-NEXT: stg %r0, 14(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: lg %r0, 14(%r3) ++; CHECK-NEXT: stg %r0, 14(%r2) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 22, i1 false) ++ ret void ++} ++ ++define void @fun22_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun22_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(22,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 22, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 22, i1 false) + ret void + } + +-define void @fun23(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun23(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun23: + ; CHECK: # %bb.0: +-; CHECK-NEXT: lg %r0, 15(%r2) +-; CHECK-NEXT: stg %r0, 15(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: lg %r0, 15(%r3) ++; CHECK-NEXT: stg %r0, 15(%r2) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 23, i1 false) ++ ret void ++} ++ ++define void @fun23_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun23_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(23,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 23, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 23, i1 false) + ret void + } + +-define void @fun24(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun24(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun24: + ; CHECK: # %bb.0: +-; CHECK-NEXT: lg %r0, 16(%r2) +-; CHECK-NEXT: stg %r0, 16(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: lg %r0, 16(%r3) ++; CHECK-NEXT: stg %r0, 16(%r2) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 24, i1 false) ++ ret void ++} ++ ++define void @fun24_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun24_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(24,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 24, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 24, i1 false) + ret void + } + +-define void @fun25(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun25(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun25: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vl %v0, 9(%r2) +-; CHECK-NEXT: vst %v0, 9(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: mvc 0(25,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 25, i1 false) ++ ret void ++} ++ ++define void @fun25_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun25_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(25,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 25, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 25, i1 false) + ret void + } + +-define void @fun26(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun26(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun26: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vl %v0, 10(%r2) +-; CHECK-NEXT: vst %v0, 10(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: mvc 0(26,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 26, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 26, i1 false) + ret void + } + +-define void @fun27(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun26_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun26_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(26,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 26, i1 false) ++ ret void ++} ++ ++define void @fun27(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun27: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vl %v0, 11(%r2) +-; CHECK-NEXT: vst %v0, 11(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: mvc 0(27,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 27, i1 false) ++ ret void ++} ++ ++define void @fun27_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun27_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(27,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 27, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 27, i1 false) + ret void + } + +-define void @fun28(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun28(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun28: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vl %v0, 12(%r2) +-; CHECK-NEXT: vst %v0, 12(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: mvc 0(28,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 28, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 28, i1 false) + ret void + } + +-define void @fun29(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun28_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun28_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(28,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 28, i1 false) ++ ret void ++} ++ ++define void @fun29(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun29: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vl %v0, 13(%r2) +-; CHECK-NEXT: vst %v0, 13(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: mvc 0(29,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 29, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 29, i1 false) + ret void + } + +-define void @fun30(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun29_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun29_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(29,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 29, i1 false) ++ ret void ++} ++ ++define void @fun30(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun30: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vl %v0, 14(%r2) +-; CHECK-NEXT: vst %v0, 14(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: mvc 0(30,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 30, i1 false) ++ ret void ++} ++ ++define void @fun30_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun30_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(30,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 30, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 30, i1 false) + ret void + } + +-define void @fun31(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun31(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun31: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vl %v0, 15(%r2) +-; CHECK-NEXT: vst %v0, 15(%r3) +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: mvc 0(31,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 31, i1 false) ++ ret void ++} ++ ++define void @fun31_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun31_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(31,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 31, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 31, i1 false) + ret void + } + +-define void @fun32(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun32(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun32: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vl %v0, 16(%r2), 4 +-; CHECK-NEXT: vst %v0, 16(%r3), 4 +-; CHECK-NEXT: vl %v0, 0(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r3), 4 ++; CHECK-NEXT: vl %v0, 16(%r3), 3 ++; CHECK-NEXT: vst %v0, 16(%r2), 3 ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 32, i1 false) ++ ret void ++} ++ ++define void @fun32_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun32_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(32,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 32, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 32, i1 false) + ret void + } + +-define void @fun33(ptr %Src, ptr %Dst, i8 %val) { ++define void @fun33(ptr %Dst, ptr %Src) { + ; CHECK-LABEL: fun33: + ; CHECK: # %bb.0: +-; CHECK-NEXT: mvc 0(33,%r3), 0(%r2) ++; CHECK-NEXT: mvc 0(33,%r2), 0(%r3) + ; CHECK-NEXT: br %r14 +- call void @llvm.memcpy.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 33, i1 false) ++ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 33, i1 false) + ret void + } + ++define void @fun33_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun33_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvc 0(33,%r2), 0(%r3) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memcpy.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 33, i1 false) ++ ret void ++} +diff --git a/llvm/test/CodeGen/SystemZ/memmove-01.ll b/llvm/test/CodeGen/SystemZ/memmove-01.ll +new file mode 100644 +index 000000000000..b9c60fbe59a7 +--- /dev/null ++++ b/llvm/test/CodeGen/SystemZ/memmove-01.ll +@@ -0,0 +1,1090 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -mcpu=z17 < %s -mtriple=s390x-linux-gnu | FileCheck %s ++; ++; Test non-volatile memmoves of small constant lengths in both aligned and ++; unaligned cases. ++ ++declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind ++ ++define void @fun1(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun1: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 1 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 1, i1 false) ++ ret void ++} ++ ++define void @fun1_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun1_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 1 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 1, i1 false) ++ ret void ++} ++ ++define void @fun2(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun2: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 2 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 2, i1 false) ++ ret void ++} ++ ++define void @fun2_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun2_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 2 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 2, i1 false) ++ ret void ++} ++ ++define void @fun3(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun3: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 3 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 3, i1 false) ++ ret void ++} ++ ++define void @fun3_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun3_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 3 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 3, i1 false) ++ ret void ++} ++ ++define void @fun4(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun4: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 4 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 4, i1 false) ++ ret void ++} ++ ++define void @fun4_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun4_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 4 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 4, i1 false) ++ ret void ++} ++ ++define void @fun5(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun5: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 5 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 5, i1 false) ++ ret void ++} ++ ++define void @fun5_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun5_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 5 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 5, i1 false) ++ ret void ++} ++ ++define void @fun6(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun6: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 6 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 6, i1 false) ++ ret void ++} ++ ++define void @fun6_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun6_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 6 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 6, i1 false) ++ ret void ++} ++ ++define void @fun7(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun7: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 7 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 7, i1 false) ++ ret void ++} ++ ++define void @fun7_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun7_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 7 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 7, i1 false) ++ ret void ++} ++ ++define void @fun8(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 8 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 8, i1 false) ++ ret void ++} ++ ++define void @fun8_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun8_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 8 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 8, i1 false) ++ ret void ++} ++ ++define void @fun9(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun9: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 9 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 9, i1 false) ++ ret void ++} ++ ++define void @fun9_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun9_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 9 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 9, i1 false) ++ ret void ++} ++ ++define void @fun10(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun10: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 10 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 10, i1 false) ++ ret void ++} ++ ++define void @fun10_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun10_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 10 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 10, i1 false) ++ ret void ++} ++ ++define void @fun11(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun11: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 11 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 11, i1 false) ++ ret void ++} ++ ++define void @fun11_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun11_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 11 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 11, i1 false) ++ ret void ++} ++ ++define void @fun12(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun12: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 12 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 12, i1 false) ++ ret void ++} ++ ++define void @fun12_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun12_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 12 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 12, i1 false) ++ ret void ++} ++ ++define void @fun13(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun13: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 13 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 13, i1 false) ++ ret void ++} ++ ++define void @fun13_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun13_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 13 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 13, i1 false) ++ ret void ++} ++ ++define void @fun14(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun14: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 14 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 14, i1 false) ++ ret void ++} ++ ++define void @fun14_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun14_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 14 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 14, i1 false) ++ ret void ++} ++ ++define void @fun15(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun15: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 15 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 15, i1 false) ++ ret void ++} ++ ++define void @fun15_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun15_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 15 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 15, i1 false) ++ ret void ++} ++ ++define void @fun16(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 16 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 16, i1 false) ++ ret void ++} ++ ++define void @fun16_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun16_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 16 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 16, i1 false) ++ ret void ++} ++ ++define void @fun17(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun17: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lb %r0, 16(%r3) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: stc %r0, 16(%r2) ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 17, i1 false) ++ ret void ++} ++ ++define void @fun17_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun17_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 17 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 17, i1 false) ++ ret void ++} ++ ++define void @fun17_unalignedSrc(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun17_unalignedSrc: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 17 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 16 %Dst, ptr align 4 %Src, i64 17, i1 false) ++ ret void ++} ++ ++define void @fun18(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun18: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lh %r0, 16(%r3) ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: sth %r0, 16(%r2) ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 18, i1 false) ++ ret void ++} ++ ++define void @fun18_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun18_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 18 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 18, i1 false) ++ ret void ++} ++ ++define void @fun18_unalignedDst(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun18_unalignedDst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 18 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 2 %Dst, ptr align 16 %Src, i64 18, i1 false) ++ ret void ++} ++ ++define void @fun19(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun19: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 19 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 19, i1 false) ++ ret void ++} ++ ++define void @fun19_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun19_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 19 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 19, i1 false) ++ ret void ++} ++ ++define void @fun20(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun20: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: l %r0, 16(%r3) ++; CHECK-NEXT: st %r0, 16(%r2) ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 20, i1 false) ++ ret void ++} ++ ++define void @fun20_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun20_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 20 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 20, i1 false) ++ ret void ++} ++ ++define void @fun20_localDst(ptr %Src) { ++; CHECK-LABEL: fun20_localDst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: aghi %r15, -184 ++; CHECK-NEXT: .cfi_def_cfa_offset 344 ++; CHECK-NEXT: vl %v0, 0(%r2), 4 ++; CHECK-NEXT: vst %v0, 164(%r15), 4 ++; CHECK-NEXT: mvc 180(4,%r15), 16(%r2) ++; CHECK-NEXT: aghi %r15, 184 ++; CHECK-NEXT: br %r14 ++ %Dst = alloca [20 x i8] ++ call void @llvm.memmove.p0.p0.i64(ptr align 16 %Dst, ptr align 16 %Src, i64 20, i1 false) ++ ret void ++} ++ ++define void @fun21(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun21: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 21 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 21, i1 false) ++ ret void ++} ++ ++define void @fun21_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun21_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 21 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 21, i1 false) ++ ret void ++} ++ ++define void @fun22(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun22: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 22 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 22, i1 false) ++ ret void ++} ++ ++define void @fun22_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun22_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 22 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 22, i1 false) ++ ret void ++} ++ ++define void @fun23(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun23: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 23 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 23, i1 false) ++ ret void ++} ++ ++define void @fun23_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun23_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 23 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 23, i1 false) ++ ret void ++} ++ ++define void @fun24(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun24: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: lg %r0, 16(%r3) ++; CHECK-NEXT: stg %r0, 16(%r2) ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 24, i1 false) ++ ret void ++} ++ ++define void @fun24_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun24_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 24 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 24, i1 false) ++ ret void ++} ++ ++define void @fun25(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun25: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 25 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 25, i1 false) ++ ret void ++} ++ ++define void @fun25_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun25_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 25 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 25, i1 false) ++ ret void ++} ++ ++define void @fun26(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun26: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 26 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 26, i1 false) ++ ret void ++} ++ ++define void @fun26_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun26_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 26 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 26, i1 false) ++ ret void ++} ++ ++define void @fun27(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun27: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 27 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 27, i1 false) ++ ret void ++} ++ ++define void @fun27_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun27_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 27 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 27, i1 false) ++ ret void ++} ++ ++define void @fun28(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun28: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 28 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 28, i1 false) ++ ret void ++} ++ ++define void @fun28_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun28_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 28 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 28, i1 false) ++ ret void ++} ++ ++define void @fun29(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun29: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 29 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 29, i1 false) ++ ret void ++} ++ ++define void @fun29_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun29_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 29 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 29, i1 false) ++ ret void ++} ++ ++define void @fun30(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun30: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 30 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 30, i1 false) ++ ret void ++} ++ ++define void @fun30_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun30_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 30 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 30, i1 false) ++ ret void ++} ++ ++define void @fun31(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun31: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 31 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 31, i1 false) ++ ret void ++} ++ ++define void @fun31_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun31_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 31 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 31, i1 false) ++ ret void ++} ++ ++define void @fun32(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vl %v0, 0(%r3), 3 ++; CHECK-NEXT: vl %v1, 16(%r3), 3 ++; CHECK-NEXT: vst %v1, 16(%r2), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 32, i1 false) ++ ret void ++} ++ ++define void @fun32_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun32_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 32 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 32, i1 false) ++ ret void ++} ++ ++define void @fun33(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun33: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 33 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 8 %Dst, ptr align 8 %Src, i64 33, i1 false) ++ ret void ++} ++ ++define void @fun33_unaligned(ptr %Dst, ptr %Src) { ++; CHECK-LABEL: fun33_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -160 ++; CHECK-NEXT: .cfi_def_cfa_offset 320 ++; CHECK-NEXT: lghi %r4, 33 ++; CHECK-NEXT: brasl %r14, memmove@PLT ++; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memmove.p0.p0.i64(ptr align 1 %Dst, ptr align 1 %Src, i64 33, i1 false) ++ ret void ++} +diff --git a/llvm/test/CodeGen/SystemZ/memset-08.ll b/llvm/test/CodeGen/SystemZ/memset-08.ll +index 931230983368..43c50320e011 100644 +--- a/llvm/test/CodeGen/SystemZ/memset-08.ll ++++ b/llvm/test/CodeGen/SystemZ/memset-08.ll +@@ -1,230 +1,1702 @@ + ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + ; RUN: llc -mcpu=z15 %s -mtriple=s390x-linux-gnu -o - | FileCheck %s + ; +-; Test memsets of small constant lengths, that should not be done with MVC. ++; Test non-volatile memsets of small constant lengths in both aligned and ++; unaligned cases. + + declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) + ++define void @reg1(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg1: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 1, i1 false) ++ ret void ++} ++ ++define void @reg1_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg1_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 1, i1 false) ++ ret void ++} ++ ++define void @reg2(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg2: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 1(%r2) ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 2, i1 false) ++ ret void ++} ++ ++define void @reg2_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg2_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 1(%r2) ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 2, i1 false) ++ ret void ++} ++ ++define void @reg3(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg3: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(2,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 3, i1 false) ++ ret void ++} ++ ++define void @reg3_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg3_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(2,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 3, i1 false) ++ ret void ++} ++ ++define void @reg4(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg4: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(3,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 4, i1 false) ++ ret void ++} ++ ++define void @reg4_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg4_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(3,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 4, i1 false) ++ ret void ++} ++ ++define void @reg5(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg5: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(4,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 5, i1 false) ++ ret void ++} ++ ++define void @reg5_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg5_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(4,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 5, i1 false) ++ ret void ++} ++ ++define void @reg6(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg6: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(5,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 6, i1 false) ++ ret void ++} ++ ++define void @reg6_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg6_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(5,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 6, i1 false) ++ ret void ++} ++ ++define void @reg7(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg7: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(6,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 7, i1 false) ++ ret void ++} ++ ++define void @reg7_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg7_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(6,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 7, i1 false) ++ ret void ++} ++ ++define void @reg8(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(7,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 8, i1 false) ++ ret void ++} ++ ++define void @reg8_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg8_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(7,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 8, i1 false) ++ ret void ++} ++ ++define void @reg9(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg9: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(8,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 9, i1 false) ++ ret void ++} ++ ++define void @reg9_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg9_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(8,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 9, i1 false) ++ ret void ++} ++ ++define void @reg10(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg10: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(9,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 10, i1 false) ++ ret void ++} ++ ++define void @reg10_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg10_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(9,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 10, i1 false) ++ ret void ++} ++ ++define void @reg11(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg11: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(10,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 11, i1 false) ++ ret void ++} ++ ++define void @reg11_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg11_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(10,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 11, i1 false) ++ ret void ++} ++ ++define void @reg12(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg12: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(11,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 12, i1 false) ++ ret void ++} ++ ++define void @reg12_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg12_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(11,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 12, i1 false) ++ ret void ++} ++ ++define void @reg13(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg13: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(12,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 13, i1 false) ++ ret void ++} ++ ++define void @reg13_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg13_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(12,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 13, i1 false) ++ ret void ++} ++ ++define void @reg14(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg14: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(13,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 14, i1 false) ++ ret void ++} ++ ++define void @reg14_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg14_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(13,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 14, i1 false) ++ ret void ++} ++ ++define void @reg15(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg15: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(14,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 15, i1 false) ++ ret void ++} ++ ++define void @reg15_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg15_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(14,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 15, i1 false) ++ ret void ++} ++ ++define void @reg16(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(15,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 16, i1 false) ++ ret void ++} ++ ++define void @reg16_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg16_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(15,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 16, i1 false) ++ ret void ++} ++ + define void @reg17(ptr %Dst, i8 %val) { + ; CHECK-LABEL: reg17: + ; CHECK: # %bb.0: +-; CHECK-NEXT: stc %r3, 0(%r2) +-; CHECK-NEXT: mvc 1(16,%r2), 0(%r2) ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(16,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 17, i1 false) ++ ret void ++} ++ ++define void @reg17_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg17_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(16,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 17, i1 false) ++ ret void ++} ++ ++define void @reg18(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg18: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vlvgp %v0, %r3, %r3 ++; CHECK-NEXT: vrepb %v0, %v0, 7 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: vsteh %v0, 16(%r2), 0 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 18, i1 false) ++ ret void ++} ++ ++define void @reg18_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg18_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(17,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 18, i1 false) ++ ret void ++} ++ ++define void @reg19(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg19: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vlvgp %v0, %r3, %r3 ++; CHECK-NEXT: vrepb %v0, %v0, 7 ++; CHECK-NEXT: vstef %v0, 15(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 19, i1 false) ++ ret void ++} ++ ++define void @reg19_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg19_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(18,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 19, i1 false) ++ ret void ++} ++ ++define void @reg20(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg20: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vlvgp %v0, %r3, %r3 ++; CHECK-NEXT: vrepb %v0, %v0, 7 ++; CHECK-NEXT: vstef %v0, 16(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 20, i1 false) ++ ret void ++} ++ ++define void @reg20_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg20_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(19,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 20, i1 false) ++ ret void ++} ++ ++define void @reg20_localDst(i8 %val) { ++; CHECK-LABEL: reg20_localDst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: aghi %r15, -184 ++; CHECK-NEXT: .cfi_def_cfa_offset 344 ++; CHECK-NEXT: vlvgp %v0, %r2, %r2 ++; CHECK-NEXT: vrepb %v0, %v0, 7 ++; CHECK-NEXT: vstef %v0, 180(%r15), 0 ++; CHECK-NEXT: vst %v0, 164(%r15), 4 ++; CHECK-NEXT: aghi %r15, 184 ++; CHECK-NEXT: br %r14 ++ %Dst = alloca [20 x i8] ++ call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 20, i1 false) ++ ret void ++} ++ ++define void @reg21(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg21: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vlvgp %v0, %r3, %r3 ++; CHECK-NEXT: vrepb %v0, %v0, 7 ++; CHECK-NEXT: vsteg %v0, 13(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 21, i1 false) ++ ret void ++} ++ ++define void @reg21_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg21_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(20,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 21, i1 false) ++ ret void ++} ++ ++define void @reg22(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg22: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vlvgp %v0, %r3, %r3 ++; CHECK-NEXT: vrepb %v0, %v0, 7 ++; CHECK-NEXT: vsteg %v0, 14(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 22, i1 false) ++ ret void ++} ++ ++define void @reg22_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg22_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(21,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 22, i1 false) ++ ret void ++} ++ ++define void @reg23(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg23: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vlvgp %v0, %r3, %r3 ++; CHECK-NEXT: vrepb %v0, %v0, 7 ++; CHECK-NEXT: vsteg %v0, 15(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 23, i1 false) ++ ret void ++} ++ ++define void @reg23_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg23_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(22,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 23, i1 false) ++ ret void ++} ++ ++define void @reg24(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg24: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vlvgp %v0, %r3, %r3 ++; CHECK-NEXT: vrepb %v0, %v0, 7 ++; CHECK-NEXT: vsteg %v0, 16(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 24, i1 false) ++ ret void ++} ++ ++define void @reg24_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg24_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(23,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 24, i1 false) ++ ret void ++} ++ ++define void @reg25(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg25: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(24,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 25, i1 false) ++ ret void ++} ++ ++define void @reg25_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg25_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(24,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 25, i1 false) ++ ret void ++} ++ ++define void @reg26(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg26: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(25,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 26, i1 false) ++ ret void ++} ++ ++define void @reg26_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg26_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(25,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 26, i1 false) ++ ret void ++} ++ ++define void @reg27(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg27: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(26,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 27, i1 false) ++ ret void ++} ++ ++define void @reg27_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg27_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(26,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 27, i1 false) ++ ret void ++} ++ ++define void @reg28(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg28: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(27,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 28, i1 false) ++ ret void ++} ++ ++define void @reg28_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg28_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(27,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 28, i1 false) ++ ret void ++} ++ ++define void @reg29(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg29: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(28,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 29, i1 false) ++ ret void ++} ++ ++define void @reg29_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg29_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(28,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 29, i1 false) ++ ret void ++} ++ ++define void @reg30(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg30: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(29,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 30, i1 false) ++ ret void ++} ++ ++define void @reg30_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg30_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(29,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 30, i1 false) ++ ret void ++} ++ ++define void @reg31(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg31: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(30,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 31, i1 false) ++ ret void ++} ++ ++define void @reg31_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg31_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(30,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 31, i1 false) ++ ret void ++} ++ ++define void @reg32(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vlvgp %v0, %r3, %r3 ++; CHECK-NEXT: vrepb %v0, %v0, 7 ++; CHECK-NEXT: vst %v0, 16(%r2), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 32, i1 false) ++ ret void ++} ++ ++define void @reg32_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg32_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(31,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 32, i1 false) ++ ret void ++} ++ ++define void @reg33(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg33: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(32,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 %val, i64 33, i1 false) ++ ret void ++} ++ ++define void @reg33_unaligned(ptr %Dst, i8 %val) { ++; CHECK-LABEL: reg33_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stc %r3, 0(%r2) ++; CHECK-NEXT: mvc 1(32,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 %val, i64 33, i1 false) ++ ret void ++} ++ ++;; Immediate value ++ ++define void @imm1(ptr %Dst) { ++; CHECK-LABEL: imm1: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 1 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 1, i64 1, i1 false) ++ ret void ++} ++ ++define void @imm1_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm1_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 255 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 -1, i64 1, i1 false) ++ ret void ++} ++ ++define void @imm2(ptr %Dst) { ++; CHECK-LABEL: imm2: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvhhi 0(%r2), 514 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 2, i64 2, i1 false) ++ ret void ++} ++ ++define void @imm2_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm2_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvhhi 0(%r2), 514 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 2, i64 2, i1 false) ++ ret void ++} ++ ++define void @imm3(ptr %Dst) { ++; CHECK-LABEL: imm3: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 2(%r2), 3 ++; CHECK-NEXT: mvhhi 0(%r2), 771 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 3, i64 3, i1 false) ++ ret void ++} ++ ++define void @imm3_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm3_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 2(%r2), 3 ++; CHECK-NEXT: mvhhi 0(%r2), 771 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 3, i64 3, i1 false) ++ ret void ++} ++ ++define void @imm4(ptr %Dst) { ++; CHECK-LABEL: imm4: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 4 ++; CHECK-NEXT: vstef %v0, 0(%r2), 0 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 4, i64 4, i1 false) ++ ret void ++} ++ ++define void @imm4_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm4_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 4 ++; CHECK-NEXT: vstef %v0, 0(%r2), 0 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 4, i64 4, i1 false) ++ ret void ++} ++ ++define void @imm5(ptr %Dst) { ++; CHECK-LABEL: imm5: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 5 ++; CHECK-NEXT: mvc 1(4,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 5, i64 5, i1 false) ++ ret void ++} ++ ++define void @imm5_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm5_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 5 ++; CHECK-NEXT: mvc 1(4,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 5, i64 5, i1 false) ++ ret void ++} ++ ++define void @imm6(ptr %Dst) { ++; CHECK-LABEL: imm6: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 6 ++; CHECK-NEXT: mvc 1(5,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 6, i64 6, i1 false) ++ ret void ++} ++ ++define void @imm6_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm6_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 6 ++; CHECK-NEXT: mvc 1(5,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 6, i64 6, i1 false) ++ ret void ++} ++ ++define void @imm7(ptr %Dst) { ++; CHECK-LABEL: imm7: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 7 ++; CHECK-NEXT: mvc 1(6,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 7, i64 7, i1 false) ++ ret void ++} ++ ++define void @imm7_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm7_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 7 ++; CHECK-NEXT: mvc 1(6,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 7, i64 7, i1 false) ++ ret void ++} ++ ++define void @imm8(ptr %Dst) { ++; CHECK-LABEL: imm8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 8 ++; CHECK-NEXT: mvc 1(7,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 8, i64 8, i1 false) ++ ret void ++} ++ ++define void @imm8_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm8_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 8 ++; CHECK-NEXT: mvc 1(7,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 8, i64 8, i1 false) ++ ret void ++} ++ ++define void @imm9(ptr %Dst) { ++; CHECK-LABEL: imm9: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 9 ++; CHECK-NEXT: mvc 1(8,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 9, i64 9, i1 false) ++ ret void ++} ++ ++define void @imm9_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm9_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 9 ++; CHECK-NEXT: mvc 1(8,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 9, i64 9, i1 false) ++ ret void ++} ++ ++define void @imm10(ptr %Dst) { ++; CHECK-LABEL: imm10: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 10 ++; CHECK-NEXT: mvc 1(9,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 10, i64 10, i1 false) ++ ret void ++} ++ ++define void @imm10_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm10_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 10 ++; CHECK-NEXT: mvc 1(9,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 10, i64 10, i1 false) ++ ret void ++} ++ ++define void @imm11(ptr %Dst) { ++; CHECK-LABEL: imm11: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 11 ++; CHECK-NEXT: mvc 1(10,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 11, i64 11, i1 false) ++ ret void ++} ++ ++define void @imm11_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm11_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 11 ++; CHECK-NEXT: mvc 1(10,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 11, i64 11, i1 false) ++ ret void ++} ++ ++define void @imm12(ptr %Dst) { ++; CHECK-LABEL: imm12: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 12 ++; CHECK-NEXT: mvc 1(11,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 12, i64 12, i1 false) ++ ret void ++} ++ ++define void @imm12_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm12_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 12 ++; CHECK-NEXT: mvc 1(11,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 12, i64 12, i1 false) ++ ret void ++} ++ ++define void @imm13(ptr %Dst) { ++; CHECK-LABEL: imm13: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 13 ++; CHECK-NEXT: mvc 1(12,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 13, i64 13, i1 false) ++ ret void ++} ++ ++define void @imm13_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm13_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 13 ++; CHECK-NEXT: mvc 1(12,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 13, i64 13, i1 false) ++ ret void ++} ++ ++define void @imm14(ptr %Dst) { ++; CHECK-LABEL: imm14: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 14 ++; CHECK-NEXT: mvc 1(13,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 14, i64 14, i1 false) ++ ret void ++} ++ ++define void @imm14_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm14_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 14 ++; CHECK-NEXT: mvc 1(13,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 14, i64 14, i1 false) ++ ret void ++} ++ ++define void @imm15(ptr %Dst) { ++; CHECK-LABEL: imm15: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 15 ++; CHECK-NEXT: mvc 1(14,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 15, i64 15, i1 false) ++ ret void ++} ++ ++define void @imm15_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm15_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 15 ++; CHECK-NEXT: mvc 1(14,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 15, i64 15, i1 false) ++ ret void ++} ++ ++define void @imm16(ptr %Dst) { ++; CHECK-LABEL: imm16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 16 ++; CHECK-NEXT: mvc 1(15,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 16, i64 16, i1 false) ++ ret void ++} ++ ++define void @imm16_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm16_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 16 ++; CHECK-NEXT: mvc 1(15,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 16, i64 16, i1 false) ++ ret void ++} ++ ++define void @imm17(ptr %Dst) { ++; CHECK-LABEL: imm17: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 17 ++; CHECK-NEXT: mvc 1(16,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 17, i64 17, i1 false) ++ ret void ++} ++ ++define void @imm17_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm17_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 17 ++; CHECK-NEXT: mvc 1(16,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 17, i64 17, i1 false) ++ ret void ++} ++ ++define void @imm18(ptr %Dst) { ++; CHECK-LABEL: imm18: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 18 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: mvhhi 16(%r2), 4626 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 18, i64 18, i1 false) ++ ret void ++} ++ ++define void @imm18_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm18_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 18 ++; CHECK-NEXT: mvc 1(17,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 18, i64 18, i1 false) ++ ret void ++} ++ ++define void @imm19(ptr %Dst) { ++; CHECK-LABEL: imm19: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 19 ++; CHECK-NEXT: vstef %v0, 15(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 19, i64 19, i1 false) ++ ret void ++} ++ ++define void @imm19_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm19_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 19 ++; CHECK-NEXT: mvc 1(18,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 19, i64 19, i1 false) ++ ret void ++} ++ ++define void @imm20(ptr %Dst) { ++; CHECK-LABEL: imm20: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 20 ++; CHECK-NEXT: vstef %v0, 16(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 20, i64 20, i1 false) ++ ret void ++} ++ ++define void @imm20_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm20_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 20 ++; CHECK-NEXT: mvc 1(19,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 20, i64 20, i1 false) ++ ret void ++} ++ ++define void @imm20_localDst() { ++; CHECK-LABEL: imm20_localDst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: aghi %r15, -184 ++; CHECK-NEXT: .cfi_def_cfa_offset 344 ++; CHECK-NEXT: vrepib %v0, 20 ++; CHECK-NEXT: vstef %v0, 180(%r15), 0 ++; CHECK-NEXT: vst %v0, 164(%r15), 4 ++; CHECK-NEXT: aghi %r15, 184 ++; CHECK-NEXT: br %r14 ++ %Dst = alloca [20 x i8] ++ call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 20, i64 20, i1 false) ++ ret void ++} ++ ++define void @imm21(ptr %Dst) { ++; CHECK-LABEL: imm21: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 21 ++; CHECK-NEXT: vsteg %v0, 13(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 21, i64 21, i1 false) ++ ret void ++} ++ ++define void @imm21_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm21_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 21 ++; CHECK-NEXT: mvc 1(20,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 21, i64 21, i1 false) ++ ret void ++} ++ ++define void @imm22(ptr %Dst) { ++; CHECK-LABEL: imm22: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 22 ++; CHECK-NEXT: vsteg %v0, 14(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 22, i64 22, i1 false) ++ ret void ++} ++ ++define void @imm22_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm22_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 22 ++; CHECK-NEXT: mvc 1(21,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 22, i64 22, i1 false) ++ ret void ++} ++ ++define void @imm23(ptr %Dst) { ++; CHECK-LABEL: imm23: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 23 ++; CHECK-NEXT: vsteg %v0, 15(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 23, i64 23, i1 false) ++ ret void ++} ++ ++define void @imm23_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm23_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 23 ++; CHECK-NEXT: mvc 1(22,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 23, i64 23, i1 false) ++ ret void ++} ++ ++define void @imm24(ptr %Dst) { ++; CHECK-LABEL: imm24: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 24 ++; CHECK-NEXT: vsteg %v0, 16(%r2), 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 24, i64 24, i1 false) ++ ret void ++} ++ ++define void @imm24_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm24_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 24 ++; CHECK-NEXT: mvc 1(23,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 24, i64 24, i1 false) ++ ret void ++} ++ ++define void @imm25(ptr %Dst) { ++; CHECK-LABEL: imm25: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 25 ++; CHECK-NEXT: mvc 1(24,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 25, i64 25, i1 false) ++ ret void ++} ++ ++define void @imm25_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm25_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 25 ++; CHECK-NEXT: mvc 1(24,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 25, i64 25, i1 false) ++ ret void ++} ++ ++define void @imm26(ptr %Dst) { ++; CHECK-LABEL: imm26: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 26 ++; CHECK-NEXT: mvc 1(25,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 26, i64 26, i1 false) ++ ret void ++} ++ ++define void @imm26_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm26_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 26 ++; CHECK-NEXT: mvc 1(25,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 26, i64 26, i1 false) ++ ret void ++} ++ ++define void @imm27(ptr %Dst) { ++; CHECK-LABEL: imm27: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 27 ++; CHECK-NEXT: mvc 1(26,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 27, i64 27, i1 false) ++ ret void ++} ++ ++define void @imm27_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm27_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 27 ++; CHECK-NEXT: mvc 1(26,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 27, i64 27, i1 false) ++ ret void ++} ++ ++define void @imm28(ptr %Dst) { ++; CHECK-LABEL: imm28: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 28 ++; CHECK-NEXT: mvc 1(27,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 28, i64 28, i1 false) ++ ret void ++} ++ ++define void @imm28_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm28_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 28 ++; CHECK-NEXT: mvc 1(27,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 28, i64 28, i1 false) ++ ret void ++} ++ ++define void @imm29(ptr %Dst) { ++; CHECK-LABEL: imm29: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 29 ++; CHECK-NEXT: mvc 1(28,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 29, i64 29, i1 false) ++ ret void ++} ++ ++define void @imm29_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm29_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 29 ++; CHECK-NEXT: mvc 1(28,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 29, i64 29, i1 false) ++ ret void ++} ++ ++define void @imm30(ptr %Dst) { ++; CHECK-LABEL: imm30: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 30 ++; CHECK-NEXT: mvc 1(29,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 30, i64 30, i1 false) ++ ret void ++} ++ ++define void @imm30_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm30_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 30 ++; CHECK-NEXT: mvc 1(29,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 30, i64 30, i1 false) ++ ret void ++} ++ ++define void @imm31(ptr %Dst) { ++; CHECK-LABEL: imm31: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 31 ++; CHECK-NEXT: mvc 1(30,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 31, i64 31, i1 false) ++ ret void ++} ++ ++define void @imm31_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm31_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 31 ++; CHECK-NEXT: mvc 1(30,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 31, i64 31, i1 false) ++ ret void ++} ++ ++define void @imm32(ptr %Dst) { ++; CHECK-LABEL: imm32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vrepib %v0, 32 ++; CHECK-NEXT: vst %v0, 16(%r2), 3 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 32, i64 32, i1 false) ++ ret void ++} ++ ++define void @imm32_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm32_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 32 ++; CHECK-NEXT: mvc 1(31,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 32, i64 32, i1 false) ++ ret void ++} ++ ++define void @imm33(ptr %Dst) { ++; CHECK-LABEL: imm33: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 33 ++; CHECK-NEXT: mvc 1(32,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 33, i64 33, i1 false) ++ ret void ++} ++ ++define void @imm33_unaligned(ptr %Dst) { ++; CHECK-LABEL: imm33_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 33 ++; CHECK-NEXT: mvc 1(32,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 33, i64 33, i1 false) ++ ret void ++} ++ ++;; zero ++ ++define void @zero1(ptr %Dst) { ++; CHECK-LABEL: zero1: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 0 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 1, i1 false) ++ ret void ++} ++ ++define void @zero1_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero1_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvi 0(%r2), 0 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 1, i1 false) ++ ret void ++} ++ ++define void @zero2(ptr %Dst) { ++; CHECK-LABEL: zero2: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvhhi 0(%r2), 0 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 2, i1 false) ++ ret void ++} ++ ++define void @zero2_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero2_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvhhi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 17, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 2, i1 false) + ret void + } + +-define void @reg18(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg18: ++define void @zero3(ptr %Dst) { ++; CHECK-LABEL: zero3: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 +-; CHECK-NEXT: vsteh %v0, 16(%r2), 0 ++; CHECK-NEXT: mvi 2(%r2), 0 ++; CHECK-NEXT: mvhhi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 18, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 3, i1 false) + ret void + } + +-define void @reg19(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg19: ++define void @zero3_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero3_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vstef %v0, 15(%r2), 0 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvi 2(%r2), 0 ++; CHECK-NEXT: mvhhi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 19, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 3, i1 false) + ret void + } + +-define void @reg20(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg20: ++define void @zero4(ptr %Dst) { ++; CHECK-LABEL: zero4: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vstef %v0, 16(%r2), 0 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvhi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 20, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 4, i1 false) + ret void + } + +-define void @reg21(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg21: ++define void @zero4_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero4_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vsteg %v0, 13(%r2), 0 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvhi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 21, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 4, i1 false) + ret void + } + +-define void @reg22(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg22: ++define void @zero5(ptr %Dst) { ++; CHECK-LABEL: zero5: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vsteg %v0, 14(%r2), 0 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvi 4(%r2), 0 ++; CHECK-NEXT: mvhi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 22, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 5, i1 false) + ret void + } + +-define void @reg23(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg23: ++define void @zero5_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero5_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vsteg %v0, 15(%r2), 0 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvi 4(%r2), 0 ++; CHECK-NEXT: mvhi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 23, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 5, i1 false) + ret void + } + +-define void @reg24(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg24: ++define void @zero6(ptr %Dst) { ++; CHECK-LABEL: zero6: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vsteg %v0, 16(%r2), 0 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvhhi 4(%r2), 0 ++; CHECK-NEXT: mvhi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 24, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 6, i1 false) + ret void + } + +-define void @reg25(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg25: ++define void @zero6_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero6_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vst %v0, 9(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvhhi 4(%r2), 0 ++; CHECK-NEXT: mvhi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 25, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 6, i1 false) + ret void + } + +-define void @reg26(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg26: ++define void @zero7(ptr %Dst) { ++; CHECK-LABEL: zero7: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vst %v0, 10(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(7,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 26, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 7, i1 false) + ret void + } + +-define void @reg27(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg27: ++define void @zero7_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero7_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vst %v0, 11(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(7,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 27, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 7, i1 false) + ret void + } + +-define void @reg28(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg28: ++define void @zero8(ptr %Dst) { ++; CHECK-LABEL: zero8: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vst %v0, 12(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvghi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 28, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 8, i1 false) + ret void + } + +-define void @reg29(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg29: ++define void @zero8_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero8_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vst %v0, 13(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvi 0(%r2), 8 ++; CHECK-NEXT: mvc 1(7,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 29, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 8, i64 8, i1 false) + ret void + } + +-define void @reg30(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg30: ++define void @zero9(ptr %Dst) { ++; CHECK-LABEL: zero9: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vst %v0, 14(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvi 8(%r2), 0 ++; CHECK-NEXT: mvghi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 30, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 9, i1 false) + ret void + } + +-define void @reg31(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg31: ++define void @zero9_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero9_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vst %v0, 15(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvi 8(%r2), 0 ++; CHECK-NEXT: mvghi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 31, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 9, i1 false) + ret void + } + +-define void @reg32(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg32: ++define void @zero10(ptr %Dst) { ++; CHECK-LABEL: zero10: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vlvgp %v0, %r3, %r3 +-; CHECK-NEXT: vrepb %v0, %v0, 7 +-; CHECK-NEXT: vst %v0, 16(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: mvhhi 8(%r2), 0 ++; CHECK-NEXT: mvghi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 32, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 10, i1 false) + ret void + } + +-define void @reg33(ptr %Dst, i8 %val) { +-; CHECK-LABEL: reg33: ++define void @zero10_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero10_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: stc %r3, 0(%r2) +-; CHECK-NEXT: mvc 1(32,%r2), 0(%r2) ++; CHECK-NEXT: mvhhi 8(%r2), 0 ++; CHECK-NEXT: mvghi 0(%r2), 0 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 %val, i64 33, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 10, i1 false) + ret void + } + +-;; Immediate value ++define void @zero11(ptr %Dst) { ++; CHECK-LABEL: zero11: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(11,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 11, i1 false) ++ ret void ++} + +-define void @imm17(ptr %Dst) { +-; CHECK-LABEL: imm17: ++define void @zero11_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero11_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: mvi 0(%r2), 1 +-; CHECK-NEXT: mvc 1(16,%r2), 0(%r2) ++; CHECK-NEXT: xc 0(11,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 1, i64 17, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 11, i1 false) + ret void + } + +-define void @imm18(ptr %Dst) { +-; CHECK-LABEL: imm18: ++define void @zero12(ptr %Dst) { ++; CHECK-LABEL: zero12: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvhi 8(%r2), 0 ++; CHECK-NEXT: mvghi 0(%r2), 0 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 12, i1 false) ++ ret void ++} ++ ++define void @zero12_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero12_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: mvhi 8(%r2), 0 ++; CHECK-NEXT: mvghi 0(%r2), 0 ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 12, i1 false) ++ ret void ++} ++ ++define void @zero13(ptr %Dst) { ++; CHECK-LABEL: zero13: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(13,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 13, i1 false) ++ ret void ++} ++ ++define void @zero13_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero13_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(13,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 13, i1 false) ++ ret void ++} ++ ++define void @zero14(ptr %Dst) { ++; CHECK-LABEL: zero14: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(14,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 14, i1 false) ++ ret void ++} ++ ++define void @zero14_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero14_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(14,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 14, i1 false) ++ ret void ++} ++ ++define void @zero15(ptr %Dst) { ++; CHECK-LABEL: zero15: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(15,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 15, i1 false) ++ ret void ++} ++ ++define void @zero15_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero15_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(15,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 15, i1 false) ++ ret void ++} ++ ++define void @zero16(ptr %Dst) { ++; CHECK-LABEL: zero16: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vgbm %v0, 65535 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 +-; CHECK-NEXT: mvhhi 16(%r2), -1 ++; CHECK-NEXT: vgbm %v0, 0 ++; CHECK-NEXT: vst %v0, 0(%r2), 3 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 -1, i64 18, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 16, i1 false) ++ ret void ++} ++ ++define void @zero16_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero16_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vgbm %v0, 0 ++; CHECK-NEXT: vst %v0, 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 16, i1 false) ++ ret void ++} ++ ++define void @zero17(ptr %Dst) { ++; CHECK-LABEL: zero17: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(17,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 17, i1 false) ++ ret void ++} ++ ++define void @zero17_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero17_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(17,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 17, i1 false) + ret void + } + +@@ -233,95 +1705,155 @@ define void @zero18(ptr %Dst) { + ; CHECK: # %bb.0: + ; CHECK-NEXT: xc 0(18,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 0, i64 18, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 18, i1 false) + ret void + } + +-define void @imm19(ptr %Dst) { +-; CHECK-LABEL: imm19: ++define void @zero18_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero18_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vrepib %v0, 1 +-; CHECK-NEXT: vstef %v0, 15(%r2), 0 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(18,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 1, i64 19, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 18, i1 false) + ret void + } + +-define void @imm20(ptr %Dst) { +-; CHECK-LABEL: imm20: ++define void @zero19(ptr %Dst) { ++; CHECK-LABEL: zero19: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vgbm %v0, 65535 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 +-; CHECK-NEXT: mvhi 16(%r2), -1 ++; CHECK-NEXT: xc 0(19,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 -1, i64 20, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 19, i1 false) + ret void + } + +-define void @imm21(ptr %Dst) { +-; CHECK-LABEL: imm21: ++define void @zero19_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero19_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vrepib %v0, 1 +-; CHECK-NEXT: vsteg %v0, 13(%r2), 0 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(19,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 1, i64 21, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 19, i1 false) + ret void + } + +-define void @imm22(ptr %Dst) { +-; CHECK-LABEL: imm22: ++define void @zero20(ptr %Dst) { ++; CHECK-LABEL: zero20: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vgbm %v0, 65535 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 +-; CHECK-NEXT: mvghi 14(%r2), -1 ++; CHECK-NEXT: xc 0(20,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 -1, i64 22, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 20, i1 false) + ret void + } + +-define void @imm23(ptr %Dst) { +-; CHECK-LABEL: imm23: ++define void @zero20_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero20_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vrepib %v0, 1 +-; CHECK-NEXT: vsteg %v0, 15(%r2), 0 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(20,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 1, i64 23, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 20, i1 false) + ret void + } + +-define void @imm24(ptr %Dst) { +-; CHECK-LABEL: imm24: ++define void @zero20_localDst() { ++; CHECK-LABEL: zero20_localDst: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vgbm %v0, 65535 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 +-; CHECK-NEXT: mvghi 16(%r2), -1 ++; CHECK-NEXT: aghi %r15, -184 ++; CHECK-NEXT: .cfi_def_cfa_offset 344 ++; CHECK-NEXT: xc 164(20,%r15), 164(%r15) ++; CHECK-NEXT: aghi %r15, 184 + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 -1, i64 24, i1 false) ++ %Dst = alloca [20 x i8] ++ call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 0, i64 20, i1 false) + ret void + } + +-define void @imm25(ptr %Dst) { +-; CHECK-LABEL: imm25: ++define void @zero21(ptr %Dst) { ++; CHECK-LABEL: zero21: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vrepib %v0, 1 +-; CHECK-NEXT: vst %v0, 9(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(21,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 1, i64 25, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 21, i1 false) + ret void + } + +-define void @imm26(ptr %Dst) { +-; CHECK-LABEL: imm26: ++define void @zero21_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero21_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(21,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 21, i1 false) ++ ret void ++} ++ ++define void @zero22(ptr %Dst) { ++; CHECK-LABEL: zero22: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(22,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 22, i1 false) ++ ret void ++} ++ ++define void @zero22_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero22_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(22,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 22, i1 false) ++ ret void ++} ++ ++define void @zero23(ptr %Dst) { ++; CHECK-LABEL: zero23: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(23,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 23, i1 false) ++ ret void ++} ++ ++define void @zero23_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero23_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(23,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 23, i1 false) ++ ret void ++} ++ ++define void @zero24(ptr %Dst) { ++; CHECK-LABEL: zero24: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(24,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 24, i1 false) ++ ret void ++} ++ ++define void @zero24_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero24_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(24,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 24, i1 false) ++ ret void ++} ++ ++define void @zero25(ptr %Dst) { ++; CHECK-LABEL: zero25: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(25,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 25, i1 false) ++ ret void ++} ++ ++define void @zero25_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero25_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vgbm %v0, 65535 +-; CHECK-NEXT: vst %v0, 10(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(25,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 -1, i64 26, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 25, i1 false) + ret void + } + +@@ -330,73 +1862,106 @@ define void @zero26(ptr %Dst) { + ; CHECK: # %bb.0: + ; CHECK-NEXT: xc 0(26,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 0, i64 26, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 26, i1 false) + ret void + } + +-define void @imm27(ptr %Dst) { +-; CHECK-LABEL: imm27: ++define void @zero26_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero26_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vrepib %v0, 1 +-; CHECK-NEXT: vst %v0, 11(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(26,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 1, i64 27, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 26, i1 false) + ret void + } + +-define void @imm28(ptr %Dst) { +-; CHECK-LABEL: imm28: ++define void @zero27(ptr %Dst) { ++; CHECK-LABEL: zero27: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vgbm %v0, 65535 +-; CHECK-NEXT: vst %v0, 12(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(27,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 -1, i64 28, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 27, i1 false) + ret void + } + +-define void @imm29(ptr %Dst) { +-; CHECK-LABEL: imm29: ++define void @zero27_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero27_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vrepib %v0, 1 +-; CHECK-NEXT: vst %v0, 13(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(27,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 1, i64 29, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 27, i1 false) + ret void + } + +-define void @imm30(ptr %Dst) { +-; CHECK-LABEL: imm30: ++define void @zero28(ptr %Dst) { ++; CHECK-LABEL: zero28: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vgbm %v0, 65535 +-; CHECK-NEXT: vst %v0, 14(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(28,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 -1, i64 30, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 28, i1 false) + ret void + } + +-define void @imm31(ptr %Dst) { +-; CHECK-LABEL: imm31: ++define void @zero28_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero28_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vrepib %v0, 1 +-; CHECK-NEXT: vst %v0, 15(%r2) +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(28,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 1, i64 31, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 28, i1 false) + ret void + } + +-define void @imm32(ptr %Dst) { +-; CHECK-LABEL: imm32: ++define void @zero29(ptr %Dst) { ++; CHECK-LABEL: zero29: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(29,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 29, i1 false) ++ ret void ++} ++ ++define void @zero29_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero29_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(29,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 29, i1 false) ++ ret void ++} ++ ++define void @zero30(ptr %Dst) { ++; CHECK-LABEL: zero30: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(30,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 30, i1 false) ++ ret void ++} ++ ++define void @zero30_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero30_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(30,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 30, i1 false) ++ ret void ++} ++ ++define void @zero31(ptr %Dst) { ++; CHECK-LABEL: zero31: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(31,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 31, i1 false) ++ ret void ++} ++ ++define void @zero31_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero31_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: vgbm %v0, 65535 +-; CHECK-NEXT: vst %v0, 16(%r2), 4 +-; CHECK-NEXT: vst %v0, 0(%r2), 4 ++; CHECK-NEXT: xc 0(31,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 -1, i64 32, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 31, i1 false) + ret void + } + +@@ -405,16 +1970,33 @@ define void @zero32(ptr %Dst) { + ; CHECK: # %bb.0: + ; CHECK-NEXT: xc 0(32,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 0, i64 32, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 32, i1 false) + ret void + } + +-define void @imm33(ptr %Dst) { +-; CHECK-LABEL: imm33: ++define void @zero32_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero32_unaligned: + ; CHECK: # %bb.0: +-; CHECK-NEXT: mvi 0(%r2), 1 +-; CHECK-NEXT: mvc 1(32,%r2), 0(%r2) ++; CHECK-NEXT: xc 0(32,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 32, i1 false) ++ ret void ++} ++ ++define void @zero33(ptr %Dst) { ++; CHECK-LABEL: zero33: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(33,%r2), 0(%r2) ++; CHECK-NEXT: br %r14 ++ call void @llvm.memset.p0.i64(ptr align 8 %Dst, i8 0, i64 33, i1 false) ++ ret void ++} ++ ++define void @zero33_unaligned(ptr %Dst) { ++; CHECK-LABEL: zero33_unaligned: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xc 0(33,%r2), 0(%r2) + ; CHECK-NEXT: br %r14 +- call void @llvm.memset.p0.i64(ptr align 16 %Dst, i8 1, i64 33, i1 false) ++ call void @llvm.memset.p0.i64(ptr align 1 %Dst, i8 0, i64 33, i1 false) + ret void + } +-- +2.54.0 + diff --git a/SOURCES/0001-SystemZ-Fix-code-in-widening-vector-multiplication-1.patch b/SOURCES/0001-SystemZ-Fix-code-in-widening-vector-multiplication-1.patch new file mode 100644 index 0000000..4de2dc9 --- /dev/null +++ b/SOURCES/0001-SystemZ-Fix-code-in-widening-vector-multiplication-1.patch @@ -0,0 +1,191 @@ +From fc12fc635b96e9fa521a33eb31336c539eed1918 Mon Sep 17 00:00:00 2001 +From: sujianIBM <98488060+sujianIBM@users.noreply.github.com> +Date: Thu, 31 Jul 2025 13:18:23 -0400 +Subject: [PATCH] [SystemZ] Fix code in widening vector multiplication + (#150836) + +Commit cdc7864 has an error which would wrongly fold widening +multiplications into an even/odd widening operation. +This PR fixes it and adds tests to check scenarios which should not be +folded into an even/odd widening operation are actually not. +--- + .../Target/SystemZ/SystemZISelLowering.cpp | 2 +- + llvm/test/CodeGen/SystemZ/vec-mul-07.ll | 114 ++++++++++++++++++ + 2 files changed, 115 insertions(+), 1 deletion(-) + +diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +index e30d7235b81b..fb0a47dc9dc4 100644 +--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp ++++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +@@ -9044,7 +9044,7 @@ static unsigned detectEvenOddMultiplyOperand(const SelectionDAG &DAG, + if (unsigned(ShuffleMask[Elt]) != 2 * Elt) + CanUseEven = false; + if (unsigned(ShuffleMask[Elt]) != 2 * Elt + 1) +- CanUseEven = true; ++ CanUseOdd = false; + } + Op = Op.getOperand(0); + if (CanUseEven) +diff --git a/llvm/test/CodeGen/SystemZ/vec-mul-07.ll b/llvm/test/CodeGen/SystemZ/vec-mul-07.ll +index 73c7a8dec5df..583561625cfc 100644 +--- a/llvm/test/CodeGen/SystemZ/vec-mul-07.ll ++++ b/llvm/test/CodeGen/SystemZ/vec-mul-07.ll +@@ -3,6 +3,23 @@ + ; + ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s + ++; Test a v16i8 -> v8i16 unsigned widening multiplication ++; which is not folded into an even/odd widening operation. ++define <8 x i16> @f1_not(<16 x i8> %val1, <16 x i8> %val2) { ++; CHECK-LABEL: f1_not: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vuplhb %v0, %v24 ++; CHECK-NEXT: vuplhb %v1, %v26 ++; CHECK-NEXT: vmlhw %v24, %v0, %v1 ++; CHECK-NEXT: br %r14 ++ %shuf1 = shufflevector <16 x i8> %val1, <16 x i8> poison, <8 x i32> ++ %zext1 = zext <8 x i8> %shuf1 to <8 x i16> ++ %shuf2 = shufflevector <16 x i8> %val2, <16 x i8> poison, <8 x i32> ++ %zext2 = zext <8 x i8> %shuf2 to <8 x i16> ++ %ret = mul <8 x i16> %zext1, %zext2 ++ ret <8 x i16> %ret ++} ++ + ; Test a v16i8 (even) -> v8i16 unsigned widening multiplication. + define <8 x i16> @f1(<16 x i8> %val1, <16 x i8> %val2) { + ; CHECK-LABEL: f1: +@@ -31,6 +48,23 @@ define <8 x i16> @f2(<16 x i8> %val1, <16 x i8> %val2) { + ret <8 x i16> %ret + } + ++; Test a v16i8 -> v8i16 signed widening multiplication ++; which is not folded into an even/odd widening operation. ++define <8 x i16> @f3_not(<16 x i8> %val1, <16 x i8> %val2) { ++; CHECK-LABEL: f3_not: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vuphb %v0, %v26 ++; CHECK-NEXT: vuphb %v1, %v24 ++; CHECK-NEXT: vmlhw %v24, %v1, %v0 ++; CHECK-NEXT: br %r14 ++ %shuf1 = shufflevector <16 x i8> %val1, <16 x i8> poison, <8 x i32> ++ %sext1 = sext <8 x i8> %shuf1 to <8 x i16> ++ %shuf2 = shufflevector <16 x i8> %val2, <16 x i8> poison, <8 x i32> ++ %sext2 = sext <8 x i8> %shuf2 to <8 x i16> ++ %ret = mul <8 x i16> %sext1, %sext2 ++ ret <8 x i16> %ret ++} ++ + ; Test a v16i8 (even) -> v8i16 signed widening multiplication. + define <8 x i16> @f3(<16 x i8> %val1, <16 x i8> %val2) { + ; CHECK-LABEL: f3: +@@ -59,6 +93,23 @@ define <8 x i16> @f4(<16 x i8> %val1, <16 x i8> %val2) { + ret <8 x i16> %ret + } + ++; Test a v8i16 -> v4i32 unsigned widening multiplication ++; which is not folded into an even/odd widening operation. ++define <4 x i32> @f5_not(<8 x i16> %val1, <8 x i16> %val2) { ++; CHECK-LABEL: f5_not: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vuplhh %v0, %v24 ++; CHECK-NEXT: vuplhh %v1, %v26 ++; CHECK-NEXT: vmlf %v24, %v0, %v1 ++; CHECK-NEXT: br %r14 ++ %shuf1 = shufflevector <8 x i16> %val1, <8 x i16> poison, <4 x i32> ++ %zext1 = zext <4 x i16> %shuf1 to <4 x i32> ++ %shuf2 = shufflevector <8 x i16> %val2, <8 x i16> poison, <4 x i32> ++ %zext2 = zext <4 x i16> %shuf2 to <4 x i32> ++ %ret = mul <4 x i32> %zext1, %zext2 ++ ret <4 x i32> %ret ++} ++ + ; Test a v8i16 (even) -> v4i32 unsigned widening multiplication. + define <4 x i32> @f5(<8 x i16> %val1, <8 x i16> %val2) { + ; CHECK-LABEL: f5: +@@ -87,6 +138,23 @@ define <4 x i32> @f6(<8 x i16> %val1, <8 x i16> %val2) { + ret <4 x i32> %ret + } + ++; Test a v8i16 -> v4i32 signed widening multiplication ++; which is not folded into an even/odd widening operation. ++define <4 x i32> @f7_not(<8 x i16> %val1, <8 x i16> %val2) { ++; CHECK-LABEL: f7_not: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vuphh %v0, %v26 ++; CHECK-NEXT: vuphh %v1, %v24 ++; CHECK-NEXT: vmlf %v24, %v1, %v0 ++; CHECK-NEXT: br %r14 ++ %shuf1 = shufflevector <8 x i16> %val1, <8 x i16> poison, <4 x i32> ++ %sext1 = sext <4 x i16> %shuf1 to <4 x i32> ++ %shuf2 = shufflevector <8 x i16> %val2, <8 x i16> poison, <4 x i32> ++ %sext2 = sext <4 x i16> %shuf2 to <4 x i32> ++ %ret = mul <4 x i32> %sext1, %sext2 ++ ret <4 x i32> %ret ++} ++ + ; Test a v8i16 (even) -> v4i32 signed widening multiplication. + define <4 x i32> @f7(<8 x i16> %val1, <8 x i16> %val2) { + ; CHECK-LABEL: f7: +@@ -115,6 +183,29 @@ define <4 x i32> @f8(<8 x i16> %val1, <8 x i16> %val2) { + ret <4 x i32> %ret + } + ++; Test a v4i32 -> v2i64 unsigned widening multiplication ++; which is not folded into an even/odd widening operation. ++define <2 x i64> @f9_not(<4 x i32> %val1, <4 x i32> %val2) { ++; CHECK-LABEL: f9_not: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vuplhf %v0, %v24 ++; CHECK-NEXT: vuplhf %v1, %v26 ++; CHECK-NEXT: vlgvg %r0, %v1, 1 ++; CHECK-NEXT: vlgvg %r1, %v0, 1 ++; CHECK-NEXT: msgr %r1, %r0 ++; CHECK-NEXT: vlgvg %r0, %v1, 0 ++; CHECK-NEXT: vlgvg %r2, %v0, 0 ++; CHECK-NEXT: msgr %r2, %r0 ++; CHECK-NEXT: vlvgp %v24, %r2, %r1 ++; CHECK-NEXT: br %r14 ++ %shuf1 = shufflevector <4 x i32> %val1, <4 x i32> poison, <2 x i32> ++ %zext1 = zext <2 x i32> %shuf1 to <2 x i64> ++ %shuf2 = shufflevector <4 x i32> %val2, <4 x i32> poison, <2 x i32> ++ %zext2 = zext <2 x i32> %shuf2 to <2 x i64> ++ %ret = mul <2 x i64> %zext1, %zext2 ++ ret <2 x i64> %ret ++} ++ + ; Test a v4i32 (even) -> v2i64 unsigned widening multiplication. + define <2 x i64> @f9(<4 x i32> %val1, <4 x i32> %val2) { + ; CHECK-LABEL: f9: +@@ -143,6 +234,29 @@ define <2 x i64> @f10(<4 x i32> %val1, <4 x i32> %val2) { + ret <2 x i64> %ret + } + ++; Test a v4i32 -> v2i64 signed widening multiplication ++; which is not folded into an even/odd widening operation. ++define <2 x i64> @f11_not(<4 x i32> %val1, <4 x i32> %val2) { ++; CHECK-LABEL: f11_not: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vuphf %v0, %v24 ++; CHECK-NEXT: vuphf %v1, %v26 ++; CHECK-NEXT: vlgvg %r0, %v1, 1 ++; CHECK-NEXT: vlgvg %r1, %v0, 1 ++; CHECK-NEXT: msgr %r1, %r0 ++; CHECK-NEXT: vlgvg %r0, %v1, 0 ++; CHECK-NEXT: vlgvg %r2, %v0, 0 ++; CHECK-NEXT: msgr %r2, %r0 ++; CHECK-NEXT: vlvgp %v24, %r2, %r1 ++; CHECK-NEXT: br %r14 ++ %shuf1 = shufflevector <4 x i32> %val1, <4 x i32> poison, <2 x i32> ++ %sext1 = sext <2 x i32> %shuf1 to <2 x i64> ++ %shuf2 = shufflevector <4 x i32> %val2, <4 x i32> poison, <2 x i32> ++ %sext2 = sext <2 x i32> %shuf2 to <2 x i64> ++ %ret = mul <2 x i64> %sext1, %sext2 ++ ret <2 x i64> %ret ++} ++ + ; Test a v4i32 (even) -> v2i64 signed widening multiplication. + define <2 x i64> @f11(<4 x i32> %val1, <4 x i32> %val2) { + ; CHECK-LABEL: f11: +-- +2.52.0 + diff --git a/SOURCES/0001-X86-Fix-EVEX-compression-for-VPMOV-2M-KMOV-with-tied.patch b/SOURCES/0001-X86-Fix-EVEX-compression-for-VPMOV-2M-KMOV-with-tied.patch new file mode 100644 index 0000000..ede6fb3 --- /dev/null +++ b/SOURCES/0001-X86-Fix-EVEX-compression-for-VPMOV-2M-KMOV-with-tied.patch @@ -0,0 +1,81 @@ +From a04c1eced55f2f3ea8dbd3d17db0b6df271c0809 Mon Sep 17 00:00:00 2001 +From: Stefan Weigl-Bosker +Date: Mon, 18 May 2026 10:47:14 -0400 +Subject: [PATCH] [X86] Fix EVEX compression for VPMOV*2M + KMOV with tied mask + use (#198220) + +When scanning uses of the mask produced by `VPMOV*2M`, we previously bailed out as soon as we encountered a write. For tied read/write mask instructions such as `KSHIFTR*`, which both read and write the same mask register, the pass could miss the use, fold the earlier `KMOV`, and erase the `VPMOV*2M` def even though the mask was still live. + +Disclaimer: LLM came up with the MIR tests and explained this pass to me. + +Fixes #198197 + +(cherry picked from commit f0fc9d0abf7024ceb5cb827b16f02c10e54fe0fd) +--- + llvm/lib/Target/X86/X86CompressEVEX.cpp | 12 ++++++------ + llvm/test/CodeGen/X86/evex-to-vex-compress.mir | 12 ++++++++++++ + 2 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/llvm/lib/Target/X86/X86CompressEVEX.cpp b/llvm/lib/Target/X86/X86CompressEVEX.cpp +index c1faf7d1aa1e..b8fbcd2582de 100644 +--- a/llvm/lib/Target/X86/X86CompressEVEX.cpp ++++ b/llvm/lib/Target/X86/X86CompressEVEX.cpp +@@ -271,12 +271,6 @@ static bool tryCompressVPMOVPattern(MachineInstr &MI, MachineBasicBlock &MBB, + + for (MachineInstr &CurMI : llvm::make_range( + std::next(MachineBasicBlock::iterator(MI)), MBB.end())) { +- if (CurMI.modifiesRegister(MaskReg, TRI)) { +- if (!KMovMI) +- return false; // Mask clobbered before use +- break; +- } +- + if (CurMI.readsRegister(MaskReg, TRI)) { + if (KMovMI) + return false; // Fail: Mask has MULTIPLE uses +@@ -295,6 +289,12 @@ static bool tryCompressVPMOVPattern(MachineInstr &MI, MachineBasicBlock &MBB, + } + } + ++ if (CurMI.modifiesRegister(MaskReg, TRI)) { ++ if (!KMovMI) ++ return false; // Mask clobbered before use ++ break; ++ } ++ + if (!KMovMI && CurMI.modifiesRegister(SrcVecReg, TRI)) { + return false; // SrcVecReg modified before it could be used by MOVMSK + } +diff --git a/llvm/test/CodeGen/X86/evex-to-vex-compress.mir b/llvm/test/CodeGen/X86/evex-to-vex-compress.mir +index b33a1d571c81..575f0c7d6a4f 100644 +--- a/llvm/test/CodeGen/X86/evex-to-vex-compress.mir ++++ b/llvm/test/CodeGen/X86/evex-to-vex-compress.mir +@@ -914,6 +914,12 @@ body: | + $k0 = VPMOVD2MZ256kr $ymm0 + $eax = KMOVBrk $k0 + $ebx = KMOVBrk $k0 ++ ; CHECK: $k0 = VPMOVD2MZ256kr $ymm0 ++ ; CHECK: $eax = KMOVBrk $k0 ++ ; CHECK: $k0 = KSHIFTRBki $k0, 2 ++ $k0 = VPMOVD2MZ256kr $ymm0 ++ $eax = KMOVBrk $k0 ++ $k0 = KSHIFTRBki $k0, 2 + ; CHECK: $k0 = VPMOVB2MZ256kr $ymm0 + ; CHECK: $eax = KMOVWrk $k0 + $k0 = VPMOVB2MZ256kr $ymm0 +@@ -1803,6 +1809,12 @@ body: | + $k0 = VPMOVD2MZ128kr $xmm0 + $eax = KMOVBrk $k0 + $ebx = KMOVBrk $k0 ++ ; CHECK: $k0 = VPMOVD2MZ128kr $xmm0 ++ ; CHECK: $eax = KMOVBrk $k0 ++ ; CHECK: $k0 = KSHIFTRBki $k0, 2 ++ $k0 = VPMOVD2MZ128kr $xmm0 ++ $eax = KMOVBrk $k0 ++ $k0 = KSHIFTRBki $k0, 2 + ; CHECK: $k0 = VPMOVB2MZ128kr $xmm0 + ; CHECK: $eax = KMOVBrk $k0 + $k0 = VPMOVB2MZ128kr $xmm0 +-- +2.50.1 + diff --git a/SOURCES/0001-cmake-Resolve-symlink-when-finding-install-prefix.patch b/SOURCES/0001-cmake-Resolve-symlink-when-finding-install-prefix.patch deleted file mode 100644 index 2b62da0..0000000 --- a/SOURCES/0001-cmake-Resolve-symlink-when-finding-install-prefix.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 06774eb8a7dc0bc36b59e53310c7f5b5d89f6c29 Mon Sep 17 00:00:00 2001 -From: Nikita Popov -Date: Tue, 28 Jan 2025 12:31:49 +0100 -Subject: [PATCH] [cmake] Resolve symlink when finding install prefix - -When determining the install prefix in LLVMConfig.cmake etc resolve -symlinks in CMAKE_CURRENT_LIST_FILE first. The motivation for this -is to support symlinks like `/usr/lib64/cmake/llvm` to -`/usr/lib64/llvm19/lib/cmake/llvm`. This only works correctly if -the paths are relative to the resolved symlink. - -It's worth noting that this *mostly* already works out of the box, -because cmake automatically does the symlink resolution when the -library is found via CMAKE_PREFIX_PATH. It just doesn't happen -when it's found via the default prefix path. ---- - cmake/Modules/FindPrefixFromConfig.cmake | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/cmake/Modules/FindPrefixFromConfig.cmake b/cmake/Modules/FindPrefixFromConfig.cmake -index 22211e4b72f2..3daff607ff84 100644 ---- a/cmake/Modules/FindPrefixFromConfig.cmake -+++ b/cmake/Modules/FindPrefixFromConfig.cmake -@@ -39,10 +39,10 @@ function(find_prefix_from_config out_var prefix_var path_to_leave) - # install prefix, and avoid hard-coding any absolute paths. - set(config_code - "# Compute the installation prefix from this LLVMConfig.cmake file location." -- "get_filename_component(${prefix_var} \"\${CMAKE_CURRENT_LIST_FILE}\" PATH)") -+ "get_filename_component(${prefix_var} \"\${CMAKE_CURRENT_LIST_FILE}\" REALPATH)") - # Construct the proper number of get_filename_component(... PATH) - # calls to compute the installation prefix. -- string(REGEX REPLACE "/" ";" _count "${path_to_leave}") -+ string(REGEX REPLACE "/" ";" _count "${path_to_leave}/plus_one") - foreach(p ${_count}) - list(APPEND config_code - "get_filename_component(${prefix_var} \"\${${prefix_var}}\" PATH)") --- -2.48.1 - diff --git a/SOURCES/0001-lld-ELF-Concatenate-.gnu.build.attributes.-sections-.patch b/SOURCES/0001-lld-ELF-Concatenate-.gnu.build.attributes.-sections-.patch new file mode 100644 index 0000000..e4d530a --- /dev/null +++ b/SOURCES/0001-lld-ELF-Concatenate-.gnu.build.attributes.-sections-.patch @@ -0,0 +1,87 @@ +From 2119e359b1f968da94ff27a4078d569e18903aef Mon Sep 17 00:00:00 2001 +From: Nikita Popov +Date: Mon, 13 Jul 2026 09:08:54 +0200 +Subject: [PATCH] [lld][ELF] Concatenate .gnu.build.attributes.* sections + (#208737) + +ld.bfd/ld.gold have been concatenating the GNU build attribute sections +since 2018: + +https://gitlab.com/gnutools/binutils-gdb/-/commit/7d8a31665739412395f6dd370d2279acd322e78e + +Do the same in LLD. These do not have a dedicated section type or flags, +so this is handled by the name-based logic. (Peculiarly, there used to +be SHF_GNU_BUILD_NOTE, but it was removed again.) + +Not concatenating these results in a huge number of sections, which +breaks tools like `file`. +--- + lld/ELF/LinkerScript.cpp | 2 +- + lld/test/ELF/gnu-build-attributes.s | 42 +++++++++++++++++++++++++++++ + 2 files changed, 43 insertions(+), 1 deletion(-) + create mode 100644 lld/test/ELF/gnu-build-attributes.s + +diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp +index 1c0a49a73962..64fb717e17d9 100644 +--- a/lld/ELF/LinkerScript.cpp ++++ b/lld/ELF/LinkerScript.cpp +@@ -119,7 +119,7 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const { + ".init_array", ".fini_array", ".tbss", + ".tdata", ".ARM.exidx", ".ARM.extab", + ".ctors", ".dtors", ".sbss", +- ".sdata", ".srodata"}) ++ ".sdata", ".srodata", ".gnu.build.attributes"}) + if (isSectionPrefix(v, s->name)) + return v; + +diff --git a/lld/test/ELF/gnu-build-attributes.s b/lld/test/ELF/gnu-build-attributes.s +new file mode 100644 +index 000000000000..79ad6c40ae50 +--- /dev/null ++++ b/lld/test/ELF/gnu-build-attributes.s +@@ -0,0 +1,42 @@ ++# REQUIRES: x86 ++ ++## Check that .gnu.build.attributes.* sections are concatenated into a single ++## .gnu.build.attributes section. ++ ++# RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu %s -o %t.o ++# RUN: ld.lld %t.o -o %t ++# RUN: llvm-readobj -n %t | FileCheck %s ++ ++# CHECK: NoteSections [ ++# CHECK-NEXT: NoteSection { ++# CHECK-NEXT: Name: .gnu.build.attributes ++# CHECK-NEXT: Offset: 0x120 ++# CHECK-NEXT: Size: 0x28 ++# CHECK-NEXT: Notes [ ++# CHECK-NEXT: { ++# CHECK-NEXT: Owner: GA${{.*}}:a1 ++# CHECK-NEXT: Data size: 0x0 ++# CHECK-NEXT: Type: OPEN ++# CHECK-NEXT: } ++# CHECK-NEXT: { ++# CHECK-NEXT: Owner: GA${{.*}}:b1 ++# CHECK-NEXT: Data size: 0x0 ++# CHECK-NEXT: Type: OPEN ++# CHECK-NEXT: } ++# CHECK-NEXT: ] ++# CHECK-NEXT: } ++# CHECK-NEXT: ] ++ ++.section ".gnu.build.attributes.text.foo", "", @note ++.balign 4 ++.long 8 ++.long 0 ++.long 0x100 ++.asciz "GA$\x03:a1" ++ ++.section ".gnu.build.attributes.text.bar", "", @note ++.balign 4 ++.long 8 ++.long 0 ++.long 0x100 ++.asciz "GA$\x03:b1" +-- +2.50.1 + diff --git a/SOURCES/0b6a1ef429.patch b/SOURCES/0b6a1ef429.patch new file mode 100644 index 0000000..8f6e2db --- /dev/null +++ b/SOURCES/0b6a1ef429.patch @@ -0,0 +1,70 @@ +From 0b6a1ef4297bb839fe26041602d32411358e0032 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Tue, 26 May 2026 01:41:01 +0200 +Subject: [PATCH] [lit] Normalize RLIM_INFINITY to "infinity" in + print_limits.py for Python 3.15+ (#190953) + +Python 3.15 changed resource.getrlimit() to return the platform's +maximum value (e.g., 18446744073709551615 on 64-bit systems) instead of +-1 for RLIM_INFINITY. This breaks lit tests that expect -1 for unlimited +resource limits. + +This patch normalizes the return value to "infinity" when it equals +RLIM_INFINITY to maintain compatibility with existing tests across all +Python versions. + +Fixes test failure: shtest-ulimit-nondarwin.py +Expected: RLIMIT_FSIZE=-1 +Got: RLIMIT_FSIZE=18446744073709551615 + +Reference: +https://github.com/python/cpython/commit/0324c726dea702282a0300225e989b19ae23b759 +Reference: https://bugzilla.redhat.com/show_bug.cgi?id=2448969 + +Analysis and testing assisted by AI. + +Assisted-by: Claude Sonnet 4.5 + +--------- + +Co-authored-by: Alexander Richardson +Co-authored-by: Tulio Magno Quites Machado Filho +--- + .../tests/Inputs/shtest-ulimit/print_limits.py | 17 +++++++++++++---- + llvm/utils/lit/tests/shtest-ulimit-nondarwin.py | 2 +- + 2 files changed, 14 insertions(+), 5 deletions(-) + +diff --git a/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py b/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py +index c732c0429e661..6c03721baf36d 100644 +--- a/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py ++++ b/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py +@@ -1,6 +1,15 @@ + import resource + +-print("RLIMIT_AS=" + str(resource.getrlimit(resource.RLIMIT_AS)[0])) +-print("RLIMIT_NOFILE=" + str(resource.getrlimit(resource.RLIMIT_NOFILE)[0])) +-print("RLIMIT_STACK=" + str(resource.getrlimit(resource.RLIMIT_STACK)[0])) +-print("RLIMIT_FSIZE=" + str(resource.getrlimit(resource.RLIMIT_FSIZE)[0])) ++ ++def normalize_limit(limit_value): ++ """Normalize RLIM_INFINITY to "infinity" for consistency across Python versions. ++ ++ Python 3.15+ returns the platform's max value (e.g., 2^64-1) instead of -1. ++ """ ++ return "infinity" if limit_value == resource.RLIM_INFINITY else str(limit_value) ++ ++ ++print("RLIMIT_AS=" + normalize_limit(resource.getrlimit(resource.RLIMIT_AS)[0])) ++print("RLIMIT_NOFILE=" + normalize_limit(resource.getrlimit(resource.RLIMIT_NOFILE)[0])) ++print("RLIMIT_STACK=" + normalize_limit(resource.getrlimit(resource.RLIMIT_STACK)[0])) ++print("RLIMIT_FSIZE=" + normalize_limit(resource.getrlimit(resource.RLIMIT_FSIZE)[0])) +diff --git a/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py b/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py +index 43811db750f80..80844d1d79460 100644 +--- a/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py ++++ b/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py +@@ -18,4 +18,4 @@ + # CHECK: ulimit -f 5 + # CHECK: RLIMIT_FSIZE=5 + # CHECK: ulimit -f unlimited +-# CHECK: RLIMIT_FSIZE=-1 ++# CHECK: RLIMIT_FSIZE=infinity diff --git a/SOURCES/20-131099.patch b/SOURCES/20-131099.patch deleted file mode 100644 index 0b66256..0000000 --- a/SOURCES/20-131099.patch +++ /dev/null @@ -1,28 +0,0 @@ -From e43271ec7438ecb78f99db134aeca274a47f6c28 Mon Sep 17 00:00:00 2001 -From: Konrad Kleine -Date: Thu, 13 Mar 2025 09:12:24 +0100 -Subject: [PATCH] Filter out configuration file from compile commands - -The commands to run the compilation when printed with `-###` contain -various irrelevant lines for the perf-training. Most of them are -filtered out already but when configured with -`CLANG_CONFIG_FILE_SYSTEM_DIR` a new line like the following is -added and needs to be filtered out: - -`Configuration file: /etc/clang/x86_64-redhat-linux-gnu-clang.cfg` ---- - clang/utils/perf-training/perf-helper.py | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/clang/utils/perf-training/perf-helper.py b/clang/utils/perf-training/perf-helper.py -index 80c6356d0497c..29904aded5ab0 100644 ---- a/clang/utils/perf-training/perf-helper.py -+++ b/clang/utils/perf-training/perf-helper.py -@@ -237,6 +237,7 @@ def get_cc1_command_for_args(cmd, env): - or ln.startswith("InstalledDir:") - or ln.startswith("LLVM Profile Note") - or ln.startswith(" (in-process)") -+ or ln.startswith("Configuration file:") - or " version " in ln - ): - continue diff --git a/SOURCES/21-146424.patch b/SOURCES/21-146424.patch deleted file mode 100644 index 5b95886..0000000 --- a/SOURCES/21-146424.patch +++ /dev/null @@ -1,94 +0,0 @@ -From eba58195932f37fb461ae17c69fc517181b99c9a Mon Sep 17 00:00:00 2001 -From: Paul Murphy -Date: Mon, 30 Jun 2025 10:13:37 -0500 -Subject: [PATCH] [PowerPC] fix lowering of SPILL_CRBIT on pwr9 and pwr10 - -If a copy exists between creation of a crbit and a spill, machine-cp -may delete the copy since it seems unaware of the relation between a cr -and crbit. A fix was previously made for the generic ppc64 lowering. It -should be applied to the pwr9 and pwr10 variants too. - -Likewise, relax and extend the pwr8 test to verify pwr9 and pwr10 -codegen too. - -This fixes #143989. ---- - llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | 17 +++++++++++------ - .../PowerPC/NoCRFieldRedefWhenSpillingCRBIT.mir | 8 +++++++- - 2 files changed, 18 insertions(+), 7 deletions(-) - -diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp -index 76dca4794e05..78d254a55fd9 100644 ---- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp -+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp -@@ -1102,13 +1102,20 @@ void PPCRegisterInfo::lowerCRBitSpilling(MachineBasicBlock::iterator II, - SpillsKnownBit = true; - break; - default: -+ // When spilling a CR bit, The super register may not be explicitly defined -+ // (i.e. it can be defined by a CR-logical that only defines the subreg) so -+ // we state that the CR field is undef. Also, in order to preserve the kill -+ // flag on the CR bit, we add it as an implicit use. -+ - // On Power10, we can use SETNBC to spill all CR bits. SETNBC will set all - // bits (specifically, it produces a -1 if the CR bit is set). Ultimately, - // the bit that is of importance to us is bit 32 (bit 0 of a 32-bit - // register), and SETNBC will set this. - if (Subtarget.isISA3_1()) { - BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::SETNBC8 : PPC::SETNBC), Reg) -- .addReg(SrcReg, RegState::Undef); -+ .addReg(SrcReg, RegState::Undef) -+ .addReg(SrcReg, RegState::Implicit | -+ getKillRegState(MI.getOperand(0).isKill())); - break; - } - -@@ -1122,16 +1129,14 @@ void PPCRegisterInfo::lowerCRBitSpilling(MachineBasicBlock::iterator II, - SrcReg == PPC::CR4LT || SrcReg == PPC::CR5LT || - SrcReg == PPC::CR6LT || SrcReg == PPC::CR7LT) { - BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::SETB8 : PPC::SETB), Reg) -- .addReg(getCRFromCRBit(SrcReg), RegState::Undef); -+ .addReg(getCRFromCRBit(SrcReg), RegState::Undef) -+ .addReg(SrcReg, RegState::Implicit | -+ getKillRegState(MI.getOperand(0).isKill())); - break; - } - } - - // We need to move the CR field that contains the CR bit we are spilling. -- // The super register may not be explicitly defined (i.e. it can be defined -- // by a CR-logical that only defines the subreg) so we state that the CR -- // field is undef. Also, in order to preserve the kill flag on the CR bit, -- // we add it as an implicit use. - BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MFOCRF8 : PPC::MFOCRF), Reg) - .addReg(getCRFromCRBit(SrcReg), RegState::Undef) - .addReg(SrcReg, -diff --git a/llvm/test/CodeGen/PowerPC/NoCRFieldRedefWhenSpillingCRBIT.mir b/llvm/test/CodeGen/PowerPC/NoCRFieldRedefWhenSpillingCRBIT.mir -index 41e21248a3f0..2796cdb3ae87 100644 ---- a/llvm/test/CodeGen/PowerPC/NoCRFieldRedefWhenSpillingCRBIT.mir -+++ b/llvm/test/CodeGen/PowerPC/NoCRFieldRedefWhenSpillingCRBIT.mir -@@ -1,6 +1,12 @@ - # RUN: llc -mcpu=pwr8 -mtriple=powerpc64le-unknown-linux-gnu -start-after \ - # RUN: virtregrewriter -ppc-asm-full-reg-names -verify-machineinstrs %s \ - # RUN: -o - | FileCheck %s -+# RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-linux-gnu -start-after \ -+# RUN: virtregrewriter -ppc-asm-full-reg-names -verify-machineinstrs %s \ -+# RUN: -o - | FileCheck %s -+# RUN: llc -mcpu=pwr10 -mtriple=powerpc64le-unknown-linux-gnu -start-after \ -+# RUN: virtregrewriter -ppc-asm-full-reg-names -verify-machineinstrs %s \ -+# RUN: -o - | FileCheck %s - - --- | - ; ModuleID = 'a.ll' -@@ -30,7 +36,7 @@ - ; Function Attrs: nounwind - declare void @llvm.stackprotector(ptr, ptr) #1 - -- attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector" "unsafe-fp-math"="false" "use-soft-float"="false" } -+ attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } - attributes #1 = { nounwind } - - !llvm.ident = !{!0} --- -2.49.0 - diff --git a/SOURCES/43cb4631c1f42dbfce78288b8ae30b5840ed59b3.patch b/SOURCES/43cb4631c1f42dbfce78288b8ae30b5840ed59b3.patch new file mode 100644 index 0000000..47b333b --- /dev/null +++ b/SOURCES/43cb4631c1f42dbfce78288b8ae30b5840ed59b3.patch @@ -0,0 +1,276 @@ +From 43cb4631c1f42dbfce78288b8ae30b5840ed59b3 Mon Sep 17 00:00:00 2001 +From: Ebuka Ezike +Date: Thu, 8 Jan 2026 18:46:03 +0000 +Subject: [PATCH] [lldb] Fix typed commands not shown on the screen (#174216) + +The cause is that in `python3.14`, `fcntl.ioctl` now throws a buffer +overflow error +when the buffer is too small or too large (see +https://github.com/python/cpython/pull/132919). This caused the Python +interpreter to fail terminal detection and not properly echo user +commands back to the screen. + +Fix by dropping the custom terminal size check entirely and using the +built-in `sys.stdin.isatty()` instead. + +Fixes #173302 +--- + .../Python/lldbsuite/test/lldbpexpect.py | 1 + + .../Interpreter/embedded_interpreter.py | 59 +++--------------- + .../python_api/file_handle/TestFileHandle.py | 48 +++++++++++++- + .../API/terminal/TestPythonInterpreterEcho.py | 62 +++++++++++++++++++ + .../Shell/ScriptInterpreter/Python/io.test | 12 ++++ + 5 files changed, 131 insertions(+), 51 deletions(-) + create mode 100644 lldb/test/API/terminal/TestPythonInterpreterEcho.py + create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/io.test + +diff --git a/lldb/packages/Python/lldbsuite/test/lldbpexpect.py b/lldb/packages/Python/lldbsuite/test/lldbpexpect.py +index 3279e1fd39f8c..03b2500fbda52 100644 +--- a/lldb/packages/Python/lldbsuite/test/lldbpexpect.py ++++ b/lldb/packages/Python/lldbsuite/test/lldbpexpect.py +@@ -10,6 +10,7 @@ + + + @skipIfRemote ++@skipIfWindows + @add_test_categories(["pexpect"]) + class PExpectTest(TestBase): + NO_DEBUG_INFO_TESTCASE = True +diff --git a/lldb/source/Interpreter/embedded_interpreter.py b/lldb/source/Interpreter/embedded_interpreter.py +index 42a9ab5fc367a..12c47bd712816 100644 +--- a/lldb/source/Interpreter/embedded_interpreter.py ++++ b/lldb/source/Interpreter/embedded_interpreter.py +@@ -32,18 +32,6 @@ def is_libedit(): + g_run_one_line_str = None + + +-def get_terminal_size(fd): +- try: +- import fcntl +- import termios +- import struct +- +- hw = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234")) +- except: +- hw = (0, 0) +- return hw +- +- + class LLDBExit(SystemExit): + pass + +@@ -74,50 +62,21 @@ def readfunc_stdio(prompt): + def run_python_interpreter(local_dict): + # Pass in the dictionary, for continuity from one session to the next. + try: +- fd = sys.stdin.fileno() +- interacted = False +- if get_terminal_size(fd)[1] == 0: +- try: +- import termios +- +- old = termios.tcgetattr(fd) +- if old[3] & termios.ECHO: +- # Need to turn off echoing and restore +- new = termios.tcgetattr(fd) +- new[3] = new[3] & ~termios.ECHO +- try: +- termios.tcsetattr(fd, termios.TCSADRAIN, new) +- interacted = True +- code.interact( +- banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.", +- readfunc=readfunc_stdio, +- local=local_dict, +- ) +- finally: +- termios.tcsetattr(fd, termios.TCSADRAIN, old) +- except: +- pass +- # Don't need to turn off echoing +- if not interacted: +- code.interact( +- banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", +- readfunc=readfunc_stdio, +- local=local_dict, +- ) +- else: +- # We have a real interactive terminal +- code.interact( +- banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", +- readfunc=readfunc, +- local=local_dict, +- ) ++ banner = "Python Interactive Interpreter. To exit, type 'quit()', 'exit()'." ++ input_func = readfunc_stdio ++ ++ is_atty = sys.stdin.isatty() ++ if is_atty: ++ banner = "Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D." ++ input_func = readfunc ++ ++ code.interact(banner=banner, readfunc=input_func, local=local_dict) + except LLDBExit: + pass + except SystemExit as e: + if e.code: + print("Script exited with code %s" % e.code) + +- + def run_one_line(local_dict, input_string): + global g_run_one_line_str + try: +diff --git a/lldb/test/API/python_api/file_handle/TestFileHandle.py b/lldb/test/API/python_api/file_handle/TestFileHandle.py +index b38585577f6f6..707044a3afb0f 100644 +--- a/lldb/test/API/python_api/file_handle/TestFileHandle.py ++++ b/lldb/test/API/python_api/file_handle/TestFileHandle.py +@@ -111,10 +111,11 @@ def setUp(self): + super(FileHandleTestCase, self).setUp() + self.out_filename = self.getBuildArtifact("output") + self.in_filename = self.getBuildArtifact("input") ++ self.err_filename = self.getBuildArtifact("error") + + def tearDown(self): + super(FileHandleTestCase, self).tearDown() +- for name in (self.out_filename, self.in_filename): ++ for name in (self.out_filename, self.in_filename, self.err_filename): + if os.path.exists(name): + os.unlink(name) + +@@ -679,6 +680,51 @@ def test_stdout_file(self): + lines = [x for x in f.read().strip().split() if x != "7"] + self.assertEqual(lines, ["foobar"]) + ++ def test_stdout_file_interactive(self): ++ """Ensure when we read stdin from a file, outputs from python goes to the right I/O stream.""" ++ with open(self.in_filename, "w") as f: ++ f.write( ++ "script --language python --\nvalue = 250 + 5\nprint(value)\nprint(vel)" ++ ) ++ ++ with open(self.out_filename, "w") as outf, open( ++ self.in_filename, "r" ++ ) as inf, open(self.err_filename, "w") as errf: ++ status = self.dbg.SetOutputFile(lldb.SBFile(outf)) ++ self.assertSuccess(status) ++ status = self.dbg.SetErrorFile(lldb.SBFile(errf)) ++ self.assertSuccess(status) ++ status = self.dbg.SetInputFile(lldb.SBFile(inf)) ++ self.assertSuccess(status) ++ auto_handle_events = True ++ spawn_thread = False ++ num_errs = 0 ++ quit_requested = False ++ stopped_for_crash = False ++ opts = lldb.SBCommandInterpreterRunOptions() ++ self.dbg.RunCommandInterpreter( ++ auto_handle_events, ++ spawn_thread, ++ opts, ++ num_errs, ++ quit_requested, ++ stopped_for_crash, ++ ) ++ self.dbg.GetOutputFile().Flush() ++ expected_out_text = "255" ++ expected_err_text = "NameError" ++ # check stdout ++ with open(self.out_filename, "r") as f: ++ out_text = f.read() ++ self.assertIn(expected_out_text, out_text) ++ self.assertNotIn(expected_err_text, out_text) ++ ++ # check stderr ++ with open(self.err_filename, "r") as f: ++ err_text = f.read() ++ self.assertIn(expected_err_text, err_text) ++ self.assertNotIn(expected_out_text, err_text) ++ + def test_identity(self): + f = io.StringIO() + sbf = lldb.SBFile(f) +diff --git a/lldb/test/API/terminal/TestPythonInterpreterEcho.py b/lldb/test/API/terminal/TestPythonInterpreterEcho.py +new file mode 100644 +index 0000000000000..758a4f9cede5a +--- /dev/null ++++ b/lldb/test/API/terminal/TestPythonInterpreterEcho.py +@@ -0,0 +1,62 @@ ++""" ++Test that typing python expression in the terminal is echoed back to stdout. ++""" ++ ++from lldbsuite.test.decorators import skipIfAsan ++from lldbsuite.test.lldbpexpect import PExpectTest ++ ++ ++@skipIfAsan ++class PythonInterpreterEchoTest(PExpectTest): ++ PYTHON_PROMPT = ">>> " ++ ++ def verify_command_echo( ++ self, command: str, expected_output: str = "", is_regex: bool = False ++ ): ++ assert self.child != None ++ child = self.child ++ self.assertIsNotNone(self.child, "expected a running lldb process.") ++ ++ child.sendline(command) ++ ++ # Build pattern list: match whichever comes first (output or prompt). ++ # This prevents waiting for a timeout if there's no match. ++ pattern = [] ++ match_expected = expected_output and len(expected_output) > 0 ++ ++ if match_expected: ++ pattern.append(expected_output) ++ pattern.append(self.PYTHON_PROMPT) ++ ++ expect_func = child.expect if is_regex else child.expect_exact ++ match_idx = expect_func(pattern) ++ if match_expected: ++ self.assertEqual( ++ match_idx, 0, "Expected output `{expected_output}` in stdout." ++ ) ++ ++ self.assertIsNotNone(self.child.before, "Expected output before prompt") ++ self.assertIsInstance(self.child.before, bytes) ++ echoed_text: str = self.child.before.decode("ascii").strip() ++ self.assertEqual( ++ command, echoed_text, f"Command '{command}' should be echoed to stdout." ++ ) ++ ++ if match_expected: ++ child.expect_exact(self.PYTHON_PROMPT) ++ ++ def test_python_interpreter_echo(self): ++ """Test that that the user typed commands is echoed to stdout""" ++ ++ self.launch(use_colors=False, dimensions=(100, 100)) ++ ++ # Enter the python interpreter. ++ self.verify_command_echo( ++ "script --language python --", expected_output="Python.*\\.", is_regex=True ++ ) ++ self.child_in_script_interpreter = True ++ ++ self.verify_command_echo("val = 300") ++ self.verify_command_echo( ++ "print('result =', 300)", expected_output="result = 300" ++ ) +diff --git a/lldb/test/Shell/ScriptInterpreter/Python/io.test b/lldb/test/Shell/ScriptInterpreter/Python/io.test +new file mode 100644 +index 0000000000000..25e3de41724e0 +--- /dev/null ++++ b/lldb/test/Shell/ScriptInterpreter/Python/io.test +@@ -0,0 +1,12 @@ ++# RUN: rm -rf %t.stdout %t.stderr ++# RUN: cat %s | %lldb --script-language python > %t.stdout 2> %t.stderr ++# RUN: cat %t.stdout | FileCheck %s --check-prefix STDOUT ++# RUN: cat %t.stderr | FileCheck %s --check-prefix STDERR ++script ++variable = 300 ++print(variable) ++print(not_value) ++quit ++ ++# STDOUT: 300 ++# STDERR: NameError{{.*}}is not defined diff --git a/SPECS/llvm.spec b/SPECS/llvm.spec index 390e30b..ed930fa 100644 --- a/SPECS/llvm.spec +++ b/SPECS/llvm.spec @@ -2,7 +2,7 @@ ## (rpmautospec version 0.6.5) ## RPMAUTOSPEC: autorelease, autochangelog %define autorelease(e:s:pb:n) %{?-p:0.}%{lua: - release_number = 2; + release_number = 1; base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}")); print(release_number + base_release_number - 1); }%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}} @@ -10,7 +10,7 @@ #region globals #region version -%global maj_ver 21 +%global maj_ver 22 %global min_ver 1 %global patch_ver 8 #global rc_ver rc3 @@ -38,13 +38,13 @@ %define bcond_override_default_offload 0 %define bcond_override_default_mlir 0 %define bcond_override_default_flang 0 +%define bcond_override_default_libclc 0 %define bcond_override_default_build_bolt 0 %define bcond_override_default_polly 0 %define bcond_override_default_pgo 0 %define bcond_override_default_libcxx 0 %define bcond_override_default_lto_build 0 %define bcond_override_default_check 0 -%define _find_debuginfo_dwz_opts %{nil} %endif # Build compat packages llvmN instead of main package for the current LLVM @@ -56,7 +56,7 @@ %bcond_without check %if %{with bundle_compat_lib} -%global compat_maj_ver 20 +%global compat_maj_ver 21 %global compat_ver %{compat_maj_ver}.1.8 %endif @@ -67,6 +67,14 @@ %bcond_without python_lit %endif +%if %{maj_ver} >= 23 +%global build_docs 0 +%global build_docs_toggle OFF +%else +%global build_docs 1 +%global build_docs_toggle ON +%endif + %bcond_without lldb %ifarch ppc64le @@ -88,7 +96,7 @@ # MLIR version 22 started to require nanobind >= 2.9, which is only available # on Fedora >= 44. -%if %{without compat_build} && %{defined fedora} && (%{maj_ver} < 22 || 0%{?fedora} >= 44) +%if %{without compat_build} && %{defined fedora} && 0%{?fedora} >= 44 %ifarch %{ix86} %bcond_with mlir %else @@ -99,7 +107,7 @@ %endif #region flang -%if %{without compat_build} && %{defined fedora} && (%{maj_ver} >= 22 && 0%{?fedora} >= 44) +%if %{without compat_build} && %{defined fedora} && 0%{?fedora} >= 44 # Link error on i686. # s390x is not supported upstream yet. %ifarch i686 s390x @@ -120,6 +128,8 @@ # Set Fortran build flags to nil because they contain flags that don't apply to flang. %global build_fflags %{nil} +%endif +#endregion flang %{lua: @@ -156,8 +166,7 @@ function print_max_procs(per_proc_mem) print(cpu) end } -%endif -#endregion flang + # The libcxx build condition also enables libcxxabi and libunwind. %if %{without compat_build} && %{defined fedora} @@ -196,16 +205,6 @@ end %endif %endif -# We only want to run the performance comparison on snapshot builds. -# centos-streams/RHEL do not have all the requirements. We tried to use pip, -# but we've seen issues on some architectures. We're now restricting this -# to Fedora. -%if %{with pgo} && %{with snapshot_build} && %{defined fedora} -%global run_pgo_perf_comparison 1 -%else -%global run_pgo_perf_comparison %{nil} -%endif - # Sanity checks for PGO and bootstrapping #---------------------------------------- %if %{with pgo} @@ -228,15 +227,16 @@ end %endif %endif -# Historically, LLD was used used at the same combinations that enabled PGO. -# If this changes, we need to update the following lines. -# However, we should be able to link using LLD even if PGO is disabled. -# Reminder: RHEL8 still builds with gcc + ld.bfd. -%if %{with pgo} -%bcond_without use_lld -%else + +%if 0%{?rhel} == 8 # RHEL8 still builds with gcc + ld.bfd. %bcond_with use_lld +%else +%bcond_without use_lld +%endif + +%if %{with pgo} && %{without use_lld} +%{error:PGO requires --with=lld} %endif # For PGO Disable LTO for now because of LLVMgold.so not found error @@ -245,6 +245,12 @@ end %global _lto_cflags %nil %endif +%if %{maj_ver} >= 23 && 0%{undefined rhel} && %{without compat_build} && %{with snapshot_build} +%bcond_without libclc +%else +%bcond_with libclc +%endif + # We are building with clang for faster/lower memory LTO builds. # See https://docs.fedoraproject.org/en-US/packaging-guidelines/#_compiler_macros # Reminder: This only works on Fedora and RHEL >= 9. @@ -276,6 +282,12 @@ end %bcond_without libedit %endif +%if %{defined rhel} && 0%{?rhel} >= 10 +%bcond_with multilib +%else +%bcond_without multilib +%endif + # Opt out of https://fedoraproject.org/wiki/Changes/fno-omit-frame-pointer # https://bugzilla.redhat.com/show_bug.cgi?id=2158587 %undefine _include_frame_pointers @@ -292,8 +304,10 @@ end # Suffixless tarball name (essentially: basename -s .tar.xz llvm-project-17.0.6.src.tar.xz) %if %{with snapshot_build} %global src_tarball_dir llvm-project-%{llvm_snapshot_git_revision} +%global src_manpage_tarball_dir llvm_man_pages-%{llvm_snapshot_yyyymmdd} %else %global src_tarball_dir llvm-project-%{maj_ver}.%{min_ver}.%{patch_ver}%{?rc_ver:-%{rc_ver}}.src +%global src_manpage_tarball_dir llvm_man_pages-%{maj_ver}.%{min_ver}.%{patch_ver} %endif # LLD uses "fast" as the algortithm for generating build-id @@ -339,6 +353,12 @@ end %global build_install_prefix %{buildroot}%{install_prefix} +%if %{with compat_build} +%global install_pythondir %{install_prefix}/lib/python%{python3_version}/site-packages +%else +%global install_pythondir %{python3_sitelib}/ +%endif + # Lower memory usage of dwz on s390x %global _dwz_low_mem_die_limit_s390x 1 %global _dwz_max_die_limit_s390x 1000000 @@ -416,16 +436,16 @@ end %global pkg_name_polly polly%{pkg_suffix} #endregion polly globals -#region PGO globals -%if 0%{run_pgo_perf_comparison} -%global llvm_test_suite_dir %{_datadir}/llvm-test-suite -%endif -#endregion PGO globals - #region flang globals %global pkg_name_flang flang%{pkg_suffix} #endregion flang globals +#region libclc globals +%if %{with libclc} +%global pkg_name_libclc libclc%{pkg_suffix} +%endif +#endregion libclc globals + #endregion globals #region packages @@ -444,9 +464,15 @@ URL: http://llvm.org %if %{with snapshot_build} Source0: https://github.com/llvm/llvm-project/archive/%{llvm_snapshot_git_revision}.tar.gz +%if %{build_docs} == 0 +Source42: https://github.com/fedora-llvm-team/llvm-snapshots/releases/download/snapshot-version-sync/%{src_manpage_tarball_dir}.tar.xz +%endif %else Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{maj_ver}.%{min_ver}.%{patch_ver}%{?rc_ver:-%{rc_ver}}/%{src_tarball_dir}.tar.xz Source1: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{maj_ver}.%{min_ver}.%{patch_ver}%{?rc_ver:-%{rc_ver}}/%{src_tarball_dir}.tar.xz.sig +%if %{build_docs} == 0 +Source42: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{maj_ver}.%{min_ver}.%{patch_ver}%{?rc_ver:-%{rc_ver}}/%{src_manpage_tarball_dir}.tar.xz +%endif %endif Source6: release-keys.asc @@ -494,9 +520,10 @@ Source1001: changelog # behind the latest packaged LLVM version. #region CLANG patches -Patch101: 0001-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch +Patch2100: 0001-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch +Patch2200: 0001-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch +Patch2300: 0001-23-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch Patch102: 0003-PATCH-clang-Don-t-install-static-libraries.patch -Patch2002: 20-131099.patch # Workaround a bug in ORC on ppc64le. # More info is available here: https://reviews.llvm.org/D159115#4641826 @@ -507,18 +534,34 @@ Patch103: 0001-Workaround-a-bug-in-ORC-on-ppc64le.patch Patch104: 0001-Driver-Give-devtoolset-path-precedence-over-Installe.patch #endregion CLANG patches -# Fix LLVMConfig.cmake when symlinks are used. -# (https://github.com/llvm/llvm-project/pull/124743 landed in LLVM 21) -Patch2003: 0001-cmake-Resolve-symlink-when-finding-install-prefix.patch +# Fix lit tests for Python 3.15+ https://bugzilla.redhat.com/show_bug.cgi?id=2448969 +Patch2209: https://github.com/llvm/llvm-project/commit/0b6a1ef429.patch + +# s390x fix for unaligned memory access performance regressions. +Patch2210: 0001-SystemZ-Avoid-unaligned-VL-VST-s-with-memcpy-memmove.patch + +# Fix a heap buffer overflow. +# https://bugzilla.redhat.com/show_bug.cgi?id=2496390 +Patch2211: 0001-LLVM-Verifier-Fix-buffer-overflow-when-verifying-gc..patch + +# Fix miscompilation. +# https://bugzilla.redhat.com/show_bug.cgi?id=2499684 +Patch2212: 0001-SDAG-Freeze-condition-in-select-of-load-fold-208683.patch +# Fix a vector miscompilation +Patch2213: 0001-X86-Fix-EVEX-compression-for-VPMOV-2M-KMOV-with-tied.patch #region LLD patches Patch106: 0001-19-Always-build-shared-libs-for-LLD.patch Patch2103: 0001-lld-Adjust-compressed-debug-level-test-for-s390x-wit.patch +Patch2214: 0001-ELF-Simplify-AArch64-relocateAlloc.-NFC.patch +Patch2215: 0001-LLD-AArch64-Make-adrp-ldr-relaxation-per-symbol-all-.patch +Patch2216: 0001-lld-ELF-Concatenate-.gnu.build.attributes.-sections-.patch #endregion LLD patches #region polly patches Patch2102: 0001-20-polly-shared-libs.patch Patch2202: 0001-22-polly-shared-libs.patch +Patch2302: 0001-22-polly-shared-libs.patch #endregion polly patches #region RHEL patches @@ -533,26 +576,21 @@ Patch503: 0002-BPF-Remove-unused-weak-symbol-__bpf_trap-166003.patch Patch504: 0003-BPF-Remove-dead-code-related-to-__bpf_trap-global-va.patch #endregion RHEL patches -# Fix a pgo miscompilation triggered by building Rust 1.87 with pgo on ppc64le. -# https://github.com/llvm/llvm-project/issues/138208 -Patch2004: 0001-CodeGenPrepare-Make-sure-instruction-get-from-SunkAd.patch -# Related CGP fix for domination, rhbz#2388223 -Patch2008: 0001-CGP-Bail-out-if-Base-Scaled-Reg-does-not-dominate-in.patch - -# Fix Power9/Power10 crbit spilling -# https://github.com/llvm/llvm-project/pull/146424 -Patch2007: 21-146424.patch - -# Fix for highway package build on ppc64le -Patch2005: 0001-PowerPC-Fix-handling-of-undefs-in-the-PPC-isSplatShu.patch -Patch2006: 0001-Add-REQUIRES-asserts-to-test-added-in-145149-because.patch - # Fix for offload builds: The DeviceRTL libraries target device code and # don't support the mtls-dialect flag, so we need to patch the clang driver # to ignore it for these targets. Patch2101: 0001-clang-Add-a-hack-to-fix-the-offload-build-with-the-m.patch Patch2201: 0001-clang-Add-a-hack-to-fix-the-offload-build-with-the-m.patch +# Fix segfault compiling plotters rust crate on ppc64le +Patch2104: 0001-PowerPC-Add-check-for-cast-when-shufflevector-172443.patch + +# Fix for lldb python shell with python 3.14 (rbhz#2428608) +Patch2105: 43cb4631c1f42dbfce78288b8ae30b5840ed59b3.patch + +# Fix for s390x vector miscompilation (rhbz#2430017) +Patch2106: 0001-SystemZ-Fix-code-in-widening-vector-multiplication-1.patch + %if 0%{?rhel} == 8 %global python3_pkgversion 3.12 %global __python3 /usr/bin/python3.12 @@ -596,40 +634,28 @@ BuildRequires: compiler-rt BuildRequires: llvm %endif -%if 0%{run_pgo_perf_comparison} -BuildRequires: llvm-test-suite -BuildRequires: tcl-devel -BuildRequires: which -# pandas and scipy are needed for running llvm-test-suite/utils/compare.py -# For RHEL we have to install it from pip and for fedora we take the RPM package. -%if 0%{?rhel} -BuildRequires: python3-pip -%else -BuildRequires: python3-pandas -BuildRequires: python3-scipy -%endif -%endif - %else %if %{with use_lld} BuildRequires: lld %endif %endif +%if %{build_docs} # This intentionally does not use python3_pkgversion. RHEL 8 does not have # python3.12-sphinx, and we are only using it as a binary anyway. BuildRequires: python3-sphinx -%if 0%{?rhel} != 8 -# RHEL 8 does not have these packages for python3.12. However, they are only -# needed for LLDB tests. -BuildRequires: python%{python3_pkgversion}-psutil -BuildRequires: python%{python3_pkgversion}-pexpect %endif -%if %{undefined rhel} +%if 0%{?rhel} != 8 +# RHEL 8 does not have these packages for python3.12. +BuildRequires: python%{python3_pkgversion}-psutil +%endif +%if %{undefined rhel} && %{build_docs} BuildRequires: python%{python3_pkgversion}-myst-parser %endif # Needed for %%multilib_fix_c_header +%if %{with multilib} BuildRequires: multilib-rpm-config +%endif %if %{with gold} BuildRequires: binutils-devel %if %{undefined rhel} || 0%{?rhel} > 8 @@ -656,20 +682,17 @@ BuildRequires: gnupg2 BuildRequires: swig BuildRequires: libxml2-devel -BuildRequires: doxygen # For clang-offload-packager BuildRequires: elfutils-libelf-devel -BuildRequires: perl -BuildRequires: perl-Data-Dumper -BuildRequires: perl-Encode BuildRequires: libffi-devel +# For scan-build +BuildRequires: perl-interpreter BuildRequires: perl-generators -# According to https://fedoraproject.org/wiki/Packaging:Emacs a package -# should BuildRequires: emacs if it packages emacs integration files. -BuildRequires: emacs +# We only need the emacs packaging macros, which are part of emacs-common. +BuildRequires: emacs-common BuildRequires: libatomic @@ -694,8 +717,6 @@ BuildRequires: python%{python3_pkgversion}-pyyaml BuildRequires: python%{python3_pkgversion}-nanobind-devel %endif -BuildRequires: graphviz - # This is required because we need "ps" when running LLDB tests BuildRequires: procps-ng @@ -955,27 +976,26 @@ Development header files for clang tools. %package -n git-clang-format%{pkg_suffix} Summary: Integration of clang-format for git Requires: %{pkg_name_clang}-tools-extra = %{version}-%{release} -Requires: git +Requires: git-core Requires: python%{python3_pkgversion} %description -n git-clang-format%{pkg_suffix} clang-format integration for git. -%if %{without compat_build} -%package -n python%{python3_pkgversion}-clang +%package -n python%{python3_pkgversion}-%{pkg_name_clang} Summary: Python3 bindings for clang Requires: %{pkg_name_clang}-devel%{?_isa} = %{version}-%{release} -Requires: python%{python3_pkgversion} +%if "%{?python3_version}" != "" +Requires: python(abi) = %{python3_version} +%endif +Provides: python%{python3_pkgversion}-clang(major) = %{maj_ver} %if 0%{?rhel} == 8 # Became python3.12-clang in LLVM 19 Obsoletes: python3-clang < 18.9 %endif -%description -n python%{python3_pkgversion}-clang +%description -n python%{python3_pkgversion}-%{pkg_name_clang} Python3 bindings for clang. - -%endif - #endregion CLANG packages #region COMPILER-RT packages @@ -1086,6 +1106,9 @@ License: Apache-2.0 WITH LLVM-exception OR NCSA URL: http://lldb.llvm.org/ Requires: %{pkg_name_clang}-libs%{?_isa} = %{version}-%{release} +%if 0%{?fedora} >= 45 || 0%{?rhel} >= 11 +Recommends: yama-ptrace-enable +%endif %if %{without compat_build} Requires: python%{python3_pkgversion}-lldb %endif @@ -1317,6 +1340,51 @@ Flang runtime libraries. %endif #endregion flang packages +#region libclc packages +%if %{with libclc} +%package -n %{pkg_name_libclc} +Summary: An open source implementation of the OpenCL 1.1 library requirements + +License: Apache-2.0 WITH LLVM-exception OR NCSA OR MIT +URL: https://libclc.llvm.org +Obsoletes: %{pkg_name_libclc}-devel < 23 + +%description -n %{pkg_name_libclc} +libclc is an open source, BSD licensed implementation of the library +requirements of the OpenCL C programming language, as specified by the +OpenCL 1.1 Specification. The following sections of the specification +impose library requirements: + + * 6.1: Supported Data Types + * 6.2.3: Explicit Conversions + * 6.2.4.2: Reinterpreting Types Using as_type() and as_typen() + * 6.9: Preprocessor Directives and Macros + * 6.11: Built-in Functionsj + * 9.3: Double Precision Floating-Point + * 9.4: 64-bit Atomics + * 9.5: Writing to 3D image memory objects + * 9.6: Half Precision Floating-Point + +libclc is intended to be used with the Clang compiler's OpenCL frontend. + +libclc is designed to be portable and extensible. To this end, it provides +generic implementations of most library requirements, allowing the target +to override the generic implementation at the granularity of individual +functions. + +libclc currently only supports the PTX target, but support for more +targets is welcome. + +%package -n %{pkg_name_libclc}-spirv +Summary: Spirv subset of %{name} + +%description -n %{pkg_name_libclc}-spirv +The %{pkg_name_libclc}-spirv package contains the spirv32-unknown-unknown/libclc.spv and +spirv64-unknown-unknown/libclc.spv files only, which are the subset required for upstream +Mesa OpenCL support with RustiCL. + +%endif +#endregion libclc packages #endregion packages #region prep @@ -1337,6 +1405,18 @@ Flang runtime libraries. # automatically apply patches based on LLVM version %autopatch -m%{compat_maj_ver}00 -M%{compat_maj_ver}99 -p1 +%if 0%{?rhel} == 8 && %{compat_maj_ver} < 22 +# The following patches have been backported from LLVM 22. +%patch -p1 -P502 +%patch -p1 -P503 +%patch -p1 -P504 +%endif + +%endif + +# Unpack the man pages first +%if %{build_docs} == 0 +%autosetup -N -T -b 42 -n %{src_manpage_tarball_dir} %endif # -T : Do Not Perform Default Archive Unpacking (without this, the th source would be unpacked twice) @@ -1355,20 +1435,12 @@ Flang runtime libraries. %if %{defined rhel} && 0%{?rhel} == 8 %patch -p1 -P501 -%if %{maj_ver} < 22 -# The following patches have been backported from LLVM 22. -%patch -p1 -P502 -%patch -p1 -P503 -%patch -p1 -P504 -%endif %endif #region LLVM preparation %py3_shebang_fix \ - llvm/test/BugPoint/compile-custom.ll.py \ - llvm/tools/opt-viewer/*.py \ - llvm/utils/update_cc_test_checks.py + llvm/tools/opt-viewer/*.py #endregion LLVM preparation @@ -1397,10 +1469,12 @@ Flang runtime libraries. #endregion COMPILER-RT preparation #region lldb preparation +%if %{build_docs} # Compat builds don't build python bindings, but should still build man pages. %if %{with compat_build} sed -i 's/LLDB_ENABLE_PYTHON/TRUE/' lldb/docs/CMakeLists.txt %endif +%endif #endregion #region libcxx preparation @@ -1442,6 +1516,8 @@ cd llvm/utils/lit %global projects clang;clang-tools-extra;lld %global runtimes compiler-rt;openmp +%global runtime_targets default + %if %{with lldb} %global projects %{projects};lldb %endif @@ -1469,6 +1545,15 @@ cd llvm/utils/lit %if %{with offload} %global runtimes %{runtimes};offload +%global runtime_targets %{runtime_targets};amdgcn-amd-amdhsa +%endif + +%if %{with libclc} || %{with offload} +%global runtime_targets %{runtime_targets};nvptx64-nvidia-cuda +%endif + +%if %{with libclc} +%global runtime_targets %{runtime_targets};spirv32-unknown-unknown;spirv64-unknown-unknown;amdgcn-amd-amdhsa-llvm %endif %global gcc_triple --gcc-triple=%{_target_cpu}-redhat-linux @@ -1500,11 +1585,9 @@ export ASMFLAGS="%{build_cflags}" # We set CLANG_DEFAULT_PIE_ON_LINUX=OFF and PPC_LINUX_DEFAULT_IEEELONGDOUBLE=ON to match the # defaults used by Fedora's GCC. -# Disable dwz on aarch64, because it takes a huge amount of time to decide not to optimize things. -# This is copied from clang. -%ifarch aarch64 +# Disable dwz because it takes a huge amount of time to decide not to +# optimize things. %define _find_debuginfo_dwz_opts %{nil} -%endif cd llvm @@ -1514,10 +1597,6 @@ OLD_LD_LIBRARY_PATH="$LD_LIBRARY_PATH" OLD_CWD="$PWD" %global builddir_instrumented $RPM_BUILD_DIR/instrumented-llvm -%if 0%{run_pgo_perf_comparison} -%global builddir_perf_pgo $RPM_BUILD_DIR/performance-of-pgoed-clang -%global builddir_perf_system $RPM_BUILD_DIR/performance-of-system-clang -%endif #region LLVM lit %if %{with python_lit} @@ -1548,14 +1627,33 @@ popd -DLLVM_BUILD_LLVM_DYLIB=ON \\\ -DLLVM_LINK_LLVM_DYLIB=ON \\\ -DCLANG_LINK_CLANG_DYLIB=ON \\\ - -DLLVM_ENABLE_FFI:BOOL=ON - -%if %{maj_ver} >= 22 -%global cmake_common_args %{cmake_common_args} \\\ + -DLLVM_ENABLE_FFI:BOOL=ON \\\ -DLLVM_ENABLE_EH=OFF -%else + +%if 0%{?rhel} == 8 +# On RHEL 8 we build with gcc, but the runtimes are built with the just built +# clang, so we need to pass clang supported compiler flags to the runtimes +# build. If we pass the gcc flags, some of the cmake feature checkes will +# fail, because they use -Werror and emit an error when passed gcc specific +# compiler flags like -specs. +# Specifically, this is required in order to fix the libomptest.so build. + +function strip_specs { + echo $1 | sed -e 's/-specs=[^ ]\+//g' +} + +CLANG_CC_CONFIG=$(pwd)/redhat-hardened-clang.cfg +CLANG_LD_CONFIG=$(pwd)/redhat-hardened-clang-ld.cfg +echo "-fPIE" >> $CLANG_CC_CONFIG +echo "-pie" >> $CLANG_LD_CONFIG +CLANG_CCFLAGS_EXTRA=--config=$CLANG_CC_CONFIG +CLANG_LDFLAGS_EXTRA=--config=$CLANG_LD_CONFIG + +CLANG_CXXFLAGS=$(strip_specs "$CXXFLAGS $CLANG_CCFLAGS_EXTRA") +CLANG_CFLAGS=$(strip_specs "$CFLAGS $CLANG_CCFLAGS_EXTRA") +CLANG_LDFLAGS=$(strip_specs "$LDFLAGS $CLANG_LDFLAGS_EXTRA") %global cmake_common_args %{cmake_common_args} \\\ - -DLLVM_ENABLE_EH=ON + -DRUNTIMES_CMAKE_ARGS="-DCMAKE_C_FLAGS=$CLANG_C_FLAGS;-DCMAKE_CXX_FLAGS=$CLANG_CXX_FLAGS;-DCMAKE_SHARED_LINKER_FLAGS=$CLANG_LD_FLAGS" %endif %if %reduce_debuginfo == 1 @@ -1573,7 +1671,7 @@ popd -DCLANG_DEFAULT_UNWINDLIB=libgcc \\\ -DCLANG_ENABLE_ARCMT:BOOL=ON \\\ -DCLANG_ENABLE_STATIC_ANALYZER:BOOL=ON \\\ - -DCLANG_INCLUDE_DOCS:BOOL=ON \\\ + -DCLANG_INCLUDE_DOCS:BOOL=%{build_docs_toggle} \\\ -DCLANG_INCLUDE_TESTS:BOOL=ON \\\ -DCLANG_PLUGIN_SUPPORT:BOOL=ON \\\ -DCLANG_REPOSITORY_STRING="%{?dist_vendor} %{version}-%{release}" \\\ @@ -1600,15 +1698,15 @@ popd # Add all *enabled* documentation targets (no doxygen but sphinx) %global cmake_config_args %{cmake_config_args} \\\ -DLLVM_ENABLE_DOXYGEN:BOOL=OFF \\\ - -DLLVM_ENABLE_SPHINX:BOOL=ON \\\ - -DLLVM_BUILD_DOCS:BOOL=ON + -DLLVM_ENABLE_SPHINX:BOOL=%{build_docs_toggle} \\\ + -DLLVM_BUILD_DOCS:BOOL=%{build_docs_toggle} # Configure sphinx: # Build man-pages but no HTML docs using sphinx %global cmake_config_args %{cmake_config_args} \\\ -DSPHINX_EXECUTABLE=/usr/bin/sphinx-build-3 \\\ -DSPHINX_OUTPUT_HTML:BOOL=OFF \\\ - -DSPHINX_OUTPUT_MAN:BOOL=ON \\\ + -DSPHINX_OUTPUT_MAN:BOOL=%{build_docs_toggle} \\\ -DSPHINX_WARNINGS_AS_ERRORS=OFF #endregion docs options @@ -1620,11 +1718,7 @@ popd %ifarch ppc64le %global cmake_config_args %{cmake_config_args} -DLLDB_TEST_USER_ARGS=--skip-category=watchpoint %endif -%if 0%{?rhel} == 8 - %global cmake_config_args %{cmake_config_args} -DLLDB_INCLUDE_TESTS:BOOL=OFF -%else - %global cmake_config_args %{cmake_config_args} -DLLDB_ENFORCE_STRICT_TEST_REQUIREMENTS:BOOL=ON -%endif +%global cmake_config_args %{cmake_config_args} -DLLDB_INCLUDE_TESTS:BOOL=OFF %endif #endregion lldb options @@ -1686,7 +1780,7 @@ popd #region mlir options %if %{with mlir} %global cmake_config_args %{cmake_config_args} \\\ - -DMLIR_INCLUDE_DOCS:BOOL=ON \\\ + -DMLIR_INCLUDE_DOCS:BOOL=%{build_docs_toggle} \\\ -DMLIR_INCLUDE_TESTS:BOOL=ON \\\ -DMLIR_INCLUDE_INTEGRATION_TESTS:BOOL=OFF \\\ -DMLIR_INSTALL_AGGREGATE_OBJECTS=OFF \\\ @@ -1701,20 +1795,26 @@ popd -DOPENMP_INSTALL_LIBDIR=%{unprefixed_libdir} \\\ -DLIBOMP_INSTALL_ALIASES=OFF -%if %{maj_ver} >= 22 && %{with offload} +%if %{with offload} # We reset the cxxflags to "" here because this is compiling for a GPU # target, where our cflags are either questionable or actively wrong. %global cmake_config_args %{cmake_config_args} \\\ - -DLLVM_RUNTIME_TARGETS='default;amdgcn-amd-amdhsa;nvptx64-nvidia-cuda' \\\ - -DRUNTIMES_nvptx64-nvidia-cuda_LLVM_ENABLE_RUNTIMES=openmp \\\ - -DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES=openmp \\\ - -DRUNTIMES_amdgcn-amd-amdhsa_CMAKE_CXX_FLAGS="" \\\ - -DRUNTIMES_nvptx64-nvidia-cuda_CMAKE_CXX_FLAGS="" + -DRUNTIMES_amdgcn-amd-amdhsa_CMAKE_CXX_FLAGS="" \\\ + -DRUNTIMES_nvptx64-nvidia-cuda_CMAKE_CXX_FLAGS="" \\\ + -DRUNTIMES_amdgcn-amd-amdhsa_CMAKE_EXE_LINKER_FLAGS="" \\\ + -DRUNTIMES_nvptx64-nvidia-cuda_CMAKE_EXE_LINKER_FLAGS="" \\\ + -DRUNTIMES_amdgcn-amd-amdhsa_CMAKE_SHARED_LINKER_FLAGS="" \\\ + -DRUNTIMES_nvptx64-nvidia-cuda_CMAKE_SHARED_LINKER_FLAGS="" \\\ + -DRUNTIMES_amdgcn-amd-amdhsa_CMAKE_MODULE_LINKER_FLAGS="" \\\ + -DRUNTIMES_nvptx64-nvidia-cuda_CMAKE_MODULE_LINKER_FLAGS="" \\\ + -DRUNTIMES_amdgcn-amd-amdhsa_CMAKE_STATIC_LINKER_FLAGS="" \\\ + -DRUNTIMES_nvptx64-nvidia-cuda_CMAKE_STATIC_LINKER_FLAGS="" \\\ + -DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES="openmp" -%if 0%{?__isa_bits} == 64 +%if 0%{?__isa_bits} == 64 && %{maj_ver} <= 22 # The following shouldn't be required, but due to a bug, we have to be # explicit about LLVM_LIBDIR_SUFFIX for nvptx64-nvidia-cuda. -# TODO: Remove this after fixing +# This got fixed in LLVM 23. # https://github.com/llvm/llvm-project/issues/159762 %global cmake_config_args %{cmake_config_args} \\\ -DRUNTIMES_nvptx64-nvidia-cuda_LLVM_LIBDIR_SUFFIX=64 @@ -1732,7 +1832,7 @@ popd #region flang options %if %{with flang} %global cmake_config_args %{cmake_config_args} \\\ - -DFLANG_INCLUDE_DOCS:BOOL=ON + -DFLANG_INCLUDE_DOCS:BOOL=%{build_docs_toggle} # Build both, shared and static flang runtime objects. # See also https://llvm.org/devmtg/2025-04/slides/quick_talk/kruse_flang-rt.pdf %global cmake_config_args %{cmake_config_args} \\\ @@ -1746,6 +1846,32 @@ popd %endif #endregion flang options +#region libclc options +%if %{with libclc} + +# Build SPIR-V targets with the SPIR-V backend, reset CXX flags and build libclc +# runtime +%global cmake_config_args %{cmake_config_args} \\\ + -DRUNTIMES_spirv32-unknown-unknown_LIBCLC_USE_SPIRV_BACKEND:BOOL=ON \\\ + -DRUNTIMES_spirv64-unknown-unknown_LIBCLC_USE_SPIRV_BACKEND:BOOL=ON \\\ + -DRUNTIMES_spirv32-unknown-unknown_CMAKE_CXX_FLAGS="" \\\ + -DRUNTIMES_spirv64-unknown-unknown_CMAKE_CXX_FLAGS="" \\\ + -DRUNTIMES_amdgcn-amd-amdhsa-llvm_CMAKE_CXX_FLAGS="" \\\ + -DRUNTIMES_spirv32-unknown-unknown_LLVM_ENABLE_RUNTIMES="libclc" \\\ + -DRUNTIMES_spirv64-unknown-unknown_LLVM_ENABLE_RUNTIMES="libclc" \\\ + -DRUNTIMES_amdgcn-amd-amdhsa-llvm_LLVM_ENABLE_RUNTIMES="libclc" +%endif +#endregion libclc options + +%if %{with offload} || %{with libclc} +# For the NVIDIA triple we potentially build both, openmp and libclc +%global combined_runtimes %{?with_offload:openmp%{?with_libclc:;}}%{?with_libclc:libclc} +%global cmake_config_args %{cmake_config_args} \\\ + -DRUNTIMES_nvptx64-nvidia-cuda_LLVM_ENABLE_RUNTIMES="%{combined_runtimes}" + +%global cmake_config_args %{cmake_config_args} \\\ + -DLLVM_RUNTIME_TARGETS="%{runtime_targets}" +%endif #region test options %global cmake_config_args %{cmake_config_args} \\\ @@ -1869,12 +1995,14 @@ fi -DLLVM_VP_COUNTERS_PER_SITE=8 %if %{defined host_clang_maj_ver} -%global cmake_config_args_instrumented %{cmake_config_args_instrumented} \\\ - -DLLVM_PROFDATA=%{_bindir}/llvm-profdata-%{host_clang_maj_ver} +%global profdata %{_bindir}/llvm-profdata-%{host_clang_maj_ver} +%global cxxfilt %{_bindir}/llvm-cxxfilt-%{host_clang_maj_ver} %else -%global cmake_config_args_instrumented %{cmake_config_args_instrumented} \\\ - -DLLVM_PROFDATA=%{_bindir}/llvm-profdata +%global profdata %{_bindir}/llvm-profdata +%global cxxfilt %{_bindir}/llvm-cxxfilt %endif +%global cmake_config_args_instrumented %{cmake_config_args_instrumented} \\\ + -DLLVM_PROFDATA=%{profdata} # TODO(kkleine): Should we see warnings like: # "function control flow change detected (hash mismatch)" @@ -1893,10 +2021,14 @@ fi %cmake_build --target generate-profdata # Show top 10 functions in the profile -llvm-profdata show --topn=10 %{builddir_instrumented}/tools/clang/utils/perf-training/clang.profdata | llvm-cxxfilt +%{profdata} show --topn=10 %{builddir_instrumented}/tools/clang/utils/perf-training/clang.profdata | %{cxxfilt} cp %{builddir_instrumented}/tools/clang/utils/perf-training/clang.profdata $RPM_BUILD_DIR/result.profdata +# The instrumented files are not needed anymore. +# Remove them in order to free disk space (~10GiB). +rm -rf %{builddir_instrumented} + #endregion Perf training %endif @@ -1974,71 +2106,17 @@ cd $OLD_CWD %cmake_build --target runtimes #endregion Final stage -#region Performance comparison -%if 0%{run_pgo_perf_comparison} - -function run_perf_test { - local build_dir=$1 - - cd %{llvm_test_suite_dir} - %__cmake -G Ninja \ - -S "%{llvm_test_suite_dir}" \ - -B "${build_dir}" \ - -DCMAKE_GENERATOR=Ninja \ - -DCMAKE_C_COMPILER=clang \ - -DCMAKE_CXX_COMPILER=clang++ \ - -DTEST_SUITE_BENCHMARKING_ONLY=ON \ - -DTEST_SUITE_COLLECT_STATS=ON \ - -DTEST_SUITE_USE_PERF=OFF \ - -DTEST_SUITE_SUBDIRS=CTMark \ - -DTEST_SUITE_RUN_BENCHMARKS=OFF \ - -DTEST_SUITE_COLLECT_CODE_SIZE=OFF \ - -C%{llvm_test_suite_dir}/cmake/caches/O3.cmake - - # Build the test-suite - %__cmake --build "${build_dir}" -j1 --verbose - - # Run the tests with lit: - %{builddir_instrumented}/bin/llvm-lit -v -o ${build_dir}/results.json ${build_dir} || true - cd $OLD_CWD -} - -# Run performance test for system clang -reset_paths -run_perf_test %{builddir_perf_system} - -# Run performance test for PGOed clang -reset_paths -FINAL_BUILD_DIR=`pwd`/%{_vpath_builddir} -export LD_LIBRARY_PATH="${FINAL_BUILD_DIR}/lib:${FINAL_BUILD_DIR}/lib64:${LD_LIBRARY_PATH}" -export PATH="${FINAL_BUILD_DIR}/bin:${OLD_PATH}" -run_perf_test %{builddir_perf_pgo} - -# Compare the performance of system and PGOed clang -%if 0%{?rhel} -python3 -m venv compare-env -source ./compare-env/bin/activate -pip install "pandas>=2.2.3" -pip install "scipy>=1.13.1" -MY_PYTHON_BIN=./compare-env/bin/python3 +%if %{with lto_build} +# The LTO cache is not needed anymore. +# Remove it in order to free disk space. +rm -rfv %{_vpath_builddir}/lto.cache %endif -system_llvm_release=$(/usr/bin/clang --version | grep -Po '[0-9]+\.[0-9]+\.[0-9]' | head -n1) -${MY_PYTHON_BIN} %{llvm_test_suite_dir}/utils/compare.py \ - --metric compile_time \ - --lhs-name ${system_llvm_release} \ - --rhs-name pgo-%{version} \ - %{builddir_perf_system}/results.json vs %{builddir_perf_pgo}/results.json > %{builddir_perf_pgo}/results-system-vs-pgo.txt || true - -echo "Result of Performance comparison between system and PGOed clang" -cat %{builddir_perf_pgo}/results-system-vs-pgo.txt - -%if 0%{?rhel} -# Deactivate virtual python environment created ealier -deactivate -%endif -%endif -#endregion Performance comparison +# Strip debug info from static libraries before the install phase because +# LLVM already consumes a lot of disk space (i.e. > 150GiB). +# The install phase duplicates files on disk, causing errors if the disk is +# too small. +RPM_BUILD_ROOT=$(realpath ..)/%{build_libdir} %__brp_strip_static_archive #region compat lib cd .. @@ -2120,7 +2198,9 @@ install %{build_libdir}/libLLVMTestingSupport.a %{buildroot}%{install_libdir} install %{build_libdir}/libLLVMTestingAnnotations.a %{buildroot}%{install_libdir} # Fix multi-lib +%if %{with multilib} %multilib_fix_c_header --file %{install_includedir}/llvm/Config/llvm-config.h +%endif %if %{without compat_build} @@ -2182,9 +2262,6 @@ ln -s ../share/clang/clang-format-diff.py %{buildroot}%{install_bindir}/clang-fo # Install the PGO profile that was used to build this LLVM into the clang package %if 0%{with pgo} cp -v $RPM_BUILD_DIR/result.profdata %{buildroot}%{install_datadir}/llvm-pgo.profdata -%if 0%{run_pgo_perf_comparison} -cp -v %{builddir_perf_pgo}/results-system-vs-pgo.txt %{buildroot}%{install_datadir}/results-system-vs-pgo.txt -%endif %endif # File in the macros file for other packages to use. We are not doing this @@ -2197,15 +2274,6 @@ sed -i -e "s|@@CLANG_MAJOR_VERSION@@|%{maj_ver}|" \ -e "s|@@CLANG_PATCH_VERSION@@|%{patch_ver}|" \ %{buildroot}%{_rpmmacrodir}/macros.%{pkg_name_clang} -# install clang python bindings -mkdir -p %{buildroot}%{python3_sitelib}/clang/ -# If we don't default to true here, we'll see this error: -# install: omitting directory 'bindings/python/clang/__pycache__' -# NOTE: this only happens if we include the gdb plugin of libomp. -# Remove the plugin with command and we're good: rm -rf %{buildroot}/%{_datarootdir}/gdb -install -p -m644 clang/bindings/python/clang/* %{buildroot}%{python3_sitelib}/clang/ -%py_byte_compile %{__python3} %{buildroot}%{python3_sitelib}/clang - # install scanbuild-py to python sitelib. mv %{buildroot}%{install_prefix}/lib/{libear,libscanbuild} %{buildroot}%{python3_sitelib} # Cannot use {libear,libscanbuild} style expansion in py_byte_compile. @@ -2229,6 +2297,15 @@ rm -Rf %{buildroot}%{install_datadir}/clang/*.el %endif +# install clang python bindings +mkdir -p %{buildroot}%{install_pythondir}/clang/ +# If we don't default to true here, we'll see this error: +# install: omitting directory 'bindings/python/clang/__pycache__' +# NOTE: this only happens if we include the gdb plugin of libomp. +# Remove the plugin with command and we're good: rm -rf %{buildroot}/%{_datarootdir}/gdb +install -p -m644 clang/bindings/python/clang/* %{buildroot}%{install_pythondir}/clang/ +%py_byte_compile %{__python3} %{buildroot}%{install_pythondir}/clang/ + # Create manpage symlink for clang++ ln -s clang-%{maj_ver}.1 %{buildroot}%{install_mandir}/man1/clang++.1 @@ -2236,15 +2313,14 @@ ln -s clang-%{maj_ver}.1 %{buildroot}%{install_mandir}/man1/clang++.1 chmod a+x %{buildroot}%{install_datadir}/scan-view/{Reporter.py,startfile.py} # multilib fix +%if %{with multilib} %multilib_fix_c_header --file %{install_includedir}/clang/Config/config.h +%endif # remove editor integrations (bbedit, sublime, emacs, vim) rm -vf %{buildroot}%{install_datadir}/clang/clang-format-bbedit.applescript rm -vf %{buildroot}%{install_datadir}/clang/clang-format-sublime.py* -# Remove unpackaged files -rm -Rvf %{buildroot}%{install_datadir}/clang-doc - # TODO: What are the Fedora guidelines for packaging bash autocomplete files? rm -vf %{buildroot}%{install_datadir}/clang/bash-autocomplete.sh @@ -2323,13 +2399,17 @@ rm %{buildroot}%{install_bindir}/llvm-omp-kernel-replay touch %{buildroot}%{_bindir}/ld %endif +%if %{build_docs} install -D -m 644 -t %{buildroot}%{install_mandir}/man1/ lld/docs/ld.lld.1 +%endif #endregion LLD installation #region LLDB installation %if %{with lldb} +%if %{with multilib} %multilib_fix_c_header --file %{install_includedir}/lldb/Host/Config.h +%endif %if %{without compat_build} # Move python package out of llvm prefix. @@ -2390,15 +2470,20 @@ rm -v %{buildroot}%{install_libdir}/libFIRAnalysis.a \ %{buildroot}%{install_libdir}/libHLFIRTransforms.a \ %{buildroot}%{install_libdir}/libCUFAttrs.a \ %{buildroot}%{install_libdir}/libCUFDialect.a \ - %{buildroot}%{install_libdir}/libFortranDecimal.a -%if %{maj_ver} >= 22 -rm -v %{buildroot}%{install_libdir}/libFortranUtils.a \ + %{buildroot}%{install_libdir}/libFortranDecimal.a \ + %{buildroot}%{install_libdir}/libFortranUtils.a \ %{buildroot}%{install_libdir}/libFIROpenACCAnalysis.a \ %{buildroot}%{install_libdir}/libFIROpenACCTransforms.a \ %{buildroot}%{install_libdir}/libMIFDialect.a -%endif + +%if %{maj_ver} < 23 find %{buildroot}%{install_includedir}/flang -type f -a ! -iname '*.mod' -delete +%else +# Remove header files that are only needed for writing plugins. +# TODO: Maybe we should package these in the future. +rm -Rf %{buildroot}%{install_includedir}/flang +%endif # this is a test binary rm -v %{buildroot}%{install_bindir}/f18-parse-demo @@ -2451,6 +2536,21 @@ move_and_replace_with_symlinks() { -exec ln -s --relative "$dest/{}" "$src/{}" \;) } +%if %{build_docs} == 0 +# Install the man pages before the symlinks below are created +cp -v ../%{src_manpage_tarball_dir}/* %{buildroot}%{install_mandir}/man1/ +%if %{without flang} +rm %{buildroot}%{install_mandir}/man1/flang.1 +%endif +%if %{without polly} +rm %{buildroot}%{install_mandir}/man1/polly.1 +%endif +%if %{without lldb} +rm %{buildroot}%{install_mandir}/man1/lldb.1 +rm %{buildroot}%{install_mandir}/man1/lldb-server.1 +%endif +%endif + %if %{without compat_build} # Move files from the llvm prefix to the system prefix and replace them with # symlinks. We do it this way around because symlinks between multilib packages @@ -2564,6 +2664,7 @@ function reset_test_opts() # Set to mark tests as expected to fail. # See https://llvm.org/docs/CommandGuide/lit.html#cmdoption-lit-xfail unset LIT_XFAIL + unset LIT_XFAIL_NOT # Set to mark tests to not even run. # See https://llvm.org/docs/CommandGuide/lit.html#cmdoption-lit-filter-out @@ -2581,6 +2682,9 @@ function reset_test_opts() # Some test (e.g. mlir) require this to be set. unset PYTHONPATH + + # We use them in some cases. + unset LIT_NUM_SHARDS LIT_RUN_SHARD } # Convert array of test names into a regex. @@ -2630,10 +2734,18 @@ reset_test_opts %cmake_build --target check-lit #endregion Test LLVM lit +#region Test libclc +%if %{with libclc} +reset_test_opts +%cmake_build --target check-libclc +%endif +#endregion Test libclc + #region Test LLVM reset_test_opts # Xfail testing of update utility tools export LIT_XFAIL="tools/UpdateTestChecks" + %cmake_build --target check-llvm #endregion Test LLVM @@ -2901,6 +3013,7 @@ test_list_filter_out+=("MLIR :: python/execution_engine.py") # if ! LD_SHOW_AUXV=1 /bin/true | grep -q arch_3_00; then test_list_filter_out+=("MLIR :: python/execution_engine.py") test_list_filter_out+=("MLIR :: python/multithreaded_tests.py") +test_list_filter_out+=("MLIR :: python/global_constructors.py") %endif %if %{with flang} @@ -3109,7 +3222,6 @@ fi %license llvm/LICENSE.TXT %{expand_bins %{expand: - bugpoint dsymutil FileCheck llc @@ -3120,6 +3232,7 @@ fi llvm-bcanalyzer llvm-bitcode-strip llvm-c-test + llvm-cas llvm-cat llvm-cfi-verify llvm-cgdata @@ -3143,6 +3256,7 @@ fi llvm-gsymutil llvm-ifs llvm-install-name-tool + llvm-ir2vec llvm-jitlink llvm-jitlink-executor llvm-lib @@ -3160,6 +3274,8 @@ fi llvm-nm llvm-objcopy llvm-objdump + llvm-offload-wrapper + llvm-offload-binary llvm-opt-report llvm-otool llvm-pdbutil @@ -3197,16 +3313,19 @@ fi yaml2obj }} -%if %{maj_ver} >= 22 +%if %{maj_ver} >= 23 %{expand_bins %{expand: - llvm-ir2vec - llvm-offload-wrapper - llvm-offload-binary + llubi + llvm-extract-bundle-entry + llvm-gpu-loader +}} +%else +%{expand_bins %{expand: + bugpoint }} %endif %{expand_mans %{expand: - bugpoint clang-tblgen dsymutil FileCheck @@ -3231,6 +3350,7 @@ fi llvm-extract llvm-ifs llvm-install-name-tool + llvm-ir2vec llvm-lib llvm-libtool-darwin llvm-link @@ -3241,6 +3361,7 @@ fi llvm-nm llvm-objcopy llvm-objdump + llvm-offload-binary llvm-opt-report llvm-otool llvm-pdbutil @@ -3263,10 +3384,14 @@ fi tblgen }} -%if %{maj_ver} >= 22 +%if %{maj_ver} >= 23 %{expand_mans %{expand: - llvm-ir2vec - llvm-offload-binary + llubi + llvm-extract-bundle-entry +}} +%else +%{expand_mans %{expand: + bugpoint }} %endif @@ -3339,11 +3464,6 @@ fi llvm-opt-fuzzer llvm-test-mustache-spec }} -%if %{maj_ver} >= 22 -%{expand_bins %{expand: - llvm-cas -}} -%endif %{expand_mans %{expand: llvm-test-mustache-spec }} @@ -3378,19 +3498,10 @@ fi }} %{install_bindir}/clang-%{maj_ver} -%{_sysconfdir}/%{pkg_name_clang}/%{_target_platform}-clang.cfg -%{_sysconfdir}/%{pkg_name_clang}/%{_target_platform}-clang++.cfg -%ifarch x86_64 -%{_sysconfdir}/%{pkg_name_clang}/i386-redhat-linux-gnu-clang.cfg -%{_sysconfdir}/%{pkg_name_clang}/i386-redhat-linux-gnu-clang++.cfg -%endif %{expand_mans clang clang++} %if 0%{with pgo} %{expand_datas %{expand: llvm-pgo.profdata }} -%if 0%{run_pgo_perf_comparison} -%{expand_datas %{expand: results-system-vs-pgo.txt }} -%endif %endif @@ -3413,6 +3524,13 @@ fi %{_libdir}/libclang-cpp.so.%{compat_maj_ver}* %endif +%{_sysconfdir}/%{pkg_name_clang}/%{_target_platform}-clang.cfg +%{_sysconfdir}/%{pkg_name_clang}/%{_target_platform}-clang++.cfg +%ifarch x86_64 +%{_sysconfdir}/%{pkg_name_clang}/i386-redhat-linux-gnu-clang.cfg +%{_sysconfdir}/%{pkg_name_clang}/i386-redhat-linux-gnu-clang++.cfg +%endif + %files -n %{pkg_name_clang}-devel %license clang/LICENSE.TXT %{expand_libs %{expand: @@ -3498,6 +3616,14 @@ fi offload-arch }} +%if %{maj_ver} >= 23 +%{expand_bins %{expand: + clang-ssaf-analyzer + clang-ssaf-format + clang-ssaf-linker +}} +%endif + %if %{without compat_build} %{_emacs_sitestartdir}/clang-format.el %{_emacs_sitestartdir}/clang-include-fixer.el @@ -3509,6 +3635,7 @@ fi clang/clang-include-fixer.py* clang/clang-tidy-diff.py* clang/run-find-all-symbols.py* + clang-doc/* }} %files -n %{pkg_name_clang}-tools-extra-devel @@ -3519,12 +3646,9 @@ fi %license clang/LICENSE.TXT %expand_bins git-clang-format -%if %{without compat_build} -%files -n python%{python3_pkgversion}-clang +%files -n python%{python3_pkgversion}-%{pkg_name_clang} %license clang/LICENSE.TXT -%{python3_sitelib}/clang/ -%endif - +%{install_pythondir}/clang/ #endregion CLANG files #region COMPILER-RT files @@ -3547,14 +3671,9 @@ fi %{_prefix}/lib/clang/%{maj_ver}/lib/%{compiler_rt_triple}/clang_rt.crtbegin.o %{_prefix}/lib/clang/%{maj_ver}/lib/%{compiler_rt_triple}/clang_rt.crtend.o -%ifnarch %{ix86} s390x riscv64 +%ifnarch %{ix86} riscv64 %{_prefix}/lib/clang/%{maj_ver}/lib/%{compiler_rt_triple}/liborc_rt.a %endif -%ifarch s390x -%if %{maj_ver} >= 22 -%{_prefix}/lib/clang/%{maj_ver}/lib/%{compiler_rt_triple}/liborc_rt.a -%endif -%endif # Additional symlink if two triples are in use. %if "%{llvm_triple}" != "%{compiler_rt_triple}" @@ -3658,13 +3777,9 @@ fi lldb-argdumper lldb-dap lldb-instr + lldb-mcp lldb-server }} -%if %{maj_ver} >= 22 -%{expand_bins %{expand: - lldb-mcp -}} -%endif # Usually, *.so symlinks are kept in devel subpackages. However, the python # bindings depend on this symlink at runtime. %{expand_libs %{expand: @@ -3679,12 +3794,10 @@ fi %files -n %{pkg_name_lldb}-devel %expand_includes lldb -%if %{maj_ver} >= 22 %{expand_bins %{expand: lldb-tblgen yaml2macho-core }} -%endif %if %{without compat_build} %files -n python%{python3_pkgversion}-lldb @@ -3699,6 +3812,7 @@ fi %files -n %{pkg_name_mlir} %license LICENSE.TXT %{expand_libs %{expand: + libmlir_apfloat_wrappers.so.%{maj_ver}* libmlir_arm_runner_utils.so.%{maj_ver}* libmlir_arm_sme_abi_stubs.so.%{maj_ver}* libmlir_async_runtime.so.%{maj_ver}* @@ -3708,12 +3822,6 @@ fi libMLIR*.so.%{maj_ver}* }} -%if %{maj_ver} >= 22 -%{expand_libs %{expand: - libmlir_apfloat_wrappers.so.%{maj_ver}* -}} -%endif - %files -n %{pkg_name_mlir}-static %expand_libs libMLIR*.a @@ -3736,6 +3844,7 @@ fi %expand_includes mlir mlir-c %{expand_libs %{expand: cmake/mlir + libmlir_apfloat_wrappers.so libmlir_arm_runner_utils.so libmlir_arm_sme_abi_stubs.so libmlir_async_runtime.so @@ -3745,19 +3854,11 @@ fi libMLIR*.so }} -%if %{maj_ver} >= 22 -%{expand_libs %{expand: - libmlir_apfloat_wrappers.so -}} -%endif - %files -n python%{python3_pkgversion}-%{pkg_name_mlir} %{python3_sitearch}/mlir/ %endif #endregion MLIR files -#region libcxx files - #region flang files %if %{with flang} %files -n %{pkg_name_flang} @@ -3772,27 +3873,16 @@ fi flang-new }} %{install_bindir}/flang-%{maj_ver} + +%if %{maj_ver} < 23 %{expand_includes %{expand: - flang/__cuda_builtins.mod - flang/__cuda_device.mod - flang/__fortran_builtins.mod - flang/__fortran_ieee_exceptions.mod - flang/__fortran_type_info.mod - flang/__ppc_intrinsics.mod - flang/__ppc_types.mod - flang/cooperative_groups.mod - flang/ieee_arithmetic.mod - flang/ieee_exceptions.mod - flang/ieee_features.mod - flang/iso_c_binding.mod - flang/iso_fortran_env.mod - flang/mma.mod - flang/cudadevice.mod - flang/iso_fortran_env_impl.mod - flang/omp_lib.mod - flang/omp_lib_kinds.mod - flang/flang_debug.mod + flang/*.mod }} +%else +%{_prefix}/lib/clang/%{maj_ver}/finclude/flang/%{llvm_triple}/*.mod +%{_prefix}/lib/clang/%{maj_ver}/finclude/flang/%{llvm_triple}/omp_lib.h +%endif + %{_sysconfdir}/%{pkg_name_clang}/%{_target_platform}-flang.cfg %ifarch x86_64 %{_sysconfdir}/%{pkg_name_clang}/i386-redhat-linux-gnu-flang.cfg @@ -3808,6 +3898,27 @@ fi %endif #region flang files +#region libclc files +%if %{with libclc} +%files -n %{pkg_name_libclc} +%license libclc/LICENSE.TXT +%doc libclc/README.md libclc/CREDITS.TXT +%{_prefix}/lib/clang/%{maj_ver}/lib/amdgcn-amd-amdhsa-llvm/libclc.bc +%{_prefix}/lib/clang/%{maj_ver}/lib/amdgcn-amd-amdhsa-llvm/libclc.a +%{_prefix}/lib/clang/%{maj_ver}/lib/nvptx64-nvidia-cuda/libclc.bc +%{_prefix}/lib/clang/%{maj_ver}/lib/nvptx64-nvidia-cuda/libclc.a + +%files -n %{pkg_name_libclc}-spirv +%license libclc/LICENSE.TXT +%doc libclc/README.md libclc/CREDITS.TXT +%{_prefix}/lib/clang/%{maj_ver}/lib/spirv32-unknown-unknown/libclc.spv +%{_prefix}/lib/clang/%{maj_ver}/lib/spirv32-unknown-unknown/libclc.a +%{_prefix}/lib/clang/%{maj_ver}/lib/spirv64-unknown-unknown/libclc.spv +%{_prefix}/lib/clang/%{maj_ver}/lib/spirv64-unknown-unknown/libclc.a +%endif +#endregion libclc files + +#region libcxx files %if %{with libcxx} %files -n %{pkg_name_libcxx} @@ -3905,6 +4016,12 @@ fi %changelog ## START: Generated by rpmautospec +* Mon Jul 20 2026 Timm Bäder - 22.1.8-1 +- Update to 22.1.8 + +* Wed Apr 08 2026 Timm Bäder - 22.1.3-1 +- Update to 22.1.3 + * Wed Feb 18 2026 Konrad Kleine - 21.1.8-2 - Remove compat libs for LLVM 20