[llvm] [X86] Remove zero extends made redundant by the byte/word fixup (PR #217923)
Jan Ječmen via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 03:53:50 PDT 2026
https://github.com/JanJecmen updated https://github.com/llvm/llvm-project/pull/217923
>From 8ac6fa8d9e265525842cfff823d7d25964d24eca Mon Sep 17 00:00:00 2001
From: Jan Jecmen <jjecmen at azul.com>
Date: Thu, 20 Aug 2026 13:28:53 +0000
Subject: [PATCH 1/3] [X86] Remove zero extends made redundant by the byte/word
fixup
Widening an 8 or 16 bit load to MOVZX32rm* leaves any later zero extend of
the loaded value doing nothing. Remove such an extend, or rewrite it as
MOV32rr when it moves the value to a different register. The redundancy
only appears once the load has been widened, which is why this runs here.
A forward walk over each block records how many low bits each 32 bit
register is known to be zero extended from; an extend is redundant when
that is no more than the number of bits it reads. Sources that are not the
low part of their super register (e.g., %ah) are excluded.
Assisted-by: Claude Opus 5 <noreply at anthropic.com>
---
llvm/lib/Target/X86/X86FixupBWInsts.cpp | 112 ++++++++++++-
.../X86/2007-08-09-IllegalX86-64Asm.ll | 2 +-
.../CodeGen/X86/GlobalISel/callingconv.ll | 4 +-
llvm/test/CodeGen/X86/atomic-load-store.ll | 1 -
.../X86/fixup-bw-eliminate-redundant-zext.mir | 157 ++++++++++++++++++
llvm/test/CodeGen/X86/isel-select-cmov.ll | 6 -
llvm/test/CodeGen/X86/isel-udiv.ll | 1 -
llvm/test/CodeGen/X86/isel-urem.ll | 1 -
llvm/test/CodeGen/X86/load-local-v4i5.ll | 2 +-
llvm/test/CodeGen/X86/popcnt.ll | 1 -
llvm/test/CodeGen/X86/pr15267.ll | 2 +-
llvm/test/CodeGen/X86/pr38539.ll | 1 -
llvm/test/CodeGen/X86/promote-assert-zext.ll | 7 +-
llvm/test/CodeGen/X86/vector-compress.ll | 122 +-------------
llvm/test/CodeGen/X86/vector-sext.ll | 28 ++--
15 files changed, 299 insertions(+), 148 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/fixup-bw-eliminate-redundant-zext.mir
diff --git a/llvm/lib/Target/X86/X86FixupBWInsts.cpp b/llvm/lib/Target/X86/X86FixupBWInsts.cpp
index 18819efd35e27..d07b7c64693f5 100644
--- a/llvm/lib/Target/X86/X86FixupBWInsts.cpp
+++ b/llvm/lib/Target/X86/X86FixupBWInsts.cpp
@@ -42,11 +42,15 @@
/// wouldn't be created, or when your know a newer processor is being
/// targeted, or when optimizing for minimum code size.
///
+/// Widening the loads in this pass can leave behind zero extends of values
+/// that are already zero extended, so as a second step these are removed.
+///
//===----------------------------------------------------------------------===//
#include "X86.h"
#include "X86InstrInfo.h"
#include "X86Subtarget.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"
@@ -60,6 +64,7 @@
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+#include <optional>
using namespace llvm;
#define FIXUPBW_DESC "X86 Byte/Word Instruction Fixup"
@@ -73,6 +78,11 @@ static cl::opt<bool>
cl::desc("Change byte and word instructions to larger sizes"),
cl::init(true), cl::Hidden);
+static cl::opt<bool> EliminateRedundantZExts(
+ "fixup-bw-eliminate-redundant-zext",
+ cl::desc("Remove zero extends of already zero extended values"),
+ cl::init(true), cl::Hidden);
+
namespace {
class X86FixupBWInstImpl {
public:
@@ -111,6 +121,10 @@ class X86FixupBWInstImpl {
// otherwise.
MachineInstr *tryReplaceInstr(MachineInstr *MI, MachineBasicBlock &MBB) const;
+ /// Remove the zero extends in \p MBB of values that an earlier instruction
+ /// in the same block (widened by this pass) has already zero extended.
+ void eliminateRedundantZeroExtends(MachineBasicBlock &MBB);
+
MachineFunction *MF = nullptr;
/// Machine instruction info used throughout the class.
@@ -174,8 +188,11 @@ bool X86FixupBWInstImpl::runOnMachineFunction(MachineFunction &MF) {
LLVM_DEBUG(dbgs() << "Start X86FixupBWInsts\n";);
// Process all basic blocks.
- for (auto &MBB : MF)
+ for (auto &MBB : MF) {
processBasicBlock(MF, MBB);
+ if (EliminateRedundantZExts)
+ eliminateRedundantZeroExtends(MBB);
+ }
LLVM_DEBUG(dbgs() << "End X86FixupBWInsts\n";);
@@ -431,6 +448,99 @@ X86FixupBWInstImpl::tryReplaceInstr(MachineInstr *MI,
return nullptr;
}
+void X86FixupBWInstImpl::eliminateRedundantZeroExtends(MachineBasicBlock &MBB) {
+ // Return the number of source bits in the zero extending mov.
+ auto DefinedZeroExtendedValueBits =
+ [](const MachineInstr &MI) -> std::optional<unsigned> {
+ switch (MI.getOpcode()) {
+ case X86::MOVZX32rm8:
+ case X86::MOVZX32rr8:
+ return 8;
+ case X86::MOVZX32rm16:
+ case X86::MOVZX32rr16:
+ return 16;
+ default:
+ return std::nullopt;
+ }
+ };
+
+ // Maps what is currently known about each 32 bit register to the number
+ // of low bits its value is known to be zero extended from: 8 for a value
+ // in [0, 0xFF] and 16 for one in [0, 0xFFFF]. Only tracks registers within
+ // a single block.
+ SmallDenseMap<MCRegister, unsigned, 8> Known;
+
+ for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
+ if (MI.isDebugInstr())
+ continue;
+
+ // Only match 8 and 16 bit register to register extends. Loads can't be
+ // eliminated. The 64 bit target versions are handled by the 32 bit
+ // versions.
+ unsigned Opc = MI.getOpcode();
+ if (Opc == X86::MOVZX32rr8 || Opc == X86::MOVZX32rr16) {
+ // The extend is redundant if the value is already zero extended from no
+ // more bits than it reads.
+ unsigned ReadBits = Opc == X86::MOVZX32rr8 ? 8 : 16;
+ MCRegister Dst = MI.getOperand(0).getReg().asMCReg();
+ MCRegister Src = MI.getOperand(1).getReg().asMCReg();
+ MCRegister SrcSuper = getX86SubSuperRegister(Src, 32);
+ auto It = Known.find(SrcSuper);
+ // Reading %ah and friends does not read the part of the super register
+ // that is known to hold the whole value, so insist on the low bits.
+ if (getX86SubSuperRegister(SrcSuper, ReadBits) == Src &&
+ It != Known.end() && It->second <= ReadBits) {
+
+ if (Dst == SrcSuper) {
+ // The extend writes back the value that is already in the register.
+ LLVM_DEBUG(dbgs() << "Removing redundant zero extend: " << MI);
+ MI.eraseFromParent();
+ continue;
+ }
+
+ // The extend is redundant but the move is not. A 32 bit copy is a
+ // byte shorter and can be eliminated at rename.
+ LLVM_DEBUG(dbgs() << "Turning zero extend into a copy: " << MI);
+ MachineInstrBuilder MIB =
+ BuildMI(MBB, MI, MIMetadata(MI), TII->get(X86::MOV32rr), Dst)
+ .addReg(SrcSuper);
+ if (unsigned OldInstrNum = MI.peekDebugInstrNum()) {
+ unsigned NewInstrNum = MIB->getDebugInstrNum(*MF);
+ MF->makeDebugValueSubstitution({OldInstrNum, 0}, {NewInstrNum, 0}, 0);
+ }
+ MI.eraseFromParent();
+
+ // The copy leaves the destination holding the value the source had,
+ // so it inherits what was known about it.
+ unsigned SrcBits = It->second;
+ Known[Dst] = SrcBits;
+ continue;
+ }
+ }
+
+ // Clear what this instruction overwrites. Two 32 bit registers never
+ // overlap, so a definition can only invalidate the one it is a sub or
+ // super register of.
+ for (const MachineOperand &MO : MI.operands()) {
+ if (MO.isRegMask()) {
+ SmallVector<MCRegister, 4> Clobbered;
+ for (auto &KnownReg : Known)
+ if (MO.clobbersPhysReg(KnownReg.first))
+ Clobbered.push_back(KnownReg.first);
+ for (MCRegister Reg : Clobbered)
+ Known.erase(Reg);
+ } else if (MO.isReg() && MO.isDef()) {
+ Known.erase(getX86SubSuperRegister(MO.getReg().asMCReg(), 32));
+ }
+ }
+
+ if (auto Bits = DefinedZeroExtendedValueBits(MI)) {
+ MCRegister Dst = MI.getOperand(0).getReg().asMCReg();
+ Known[getX86SubSuperRegister(Dst, 32)] = *Bits;
+ }
+ }
+}
+
void X86FixupBWInstImpl::processBasicBlock(MachineFunction &MF,
MachineBasicBlock &MBB) {
diff --git a/llvm/test/CodeGen/X86/2007-08-09-IllegalX86-64Asm.ll b/llvm/test/CodeGen/X86/2007-08-09-IllegalX86-64Asm.ll
index 7bdc4e19a1cf6..ba0eaa3013a79 100644
--- a/llvm/test/CodeGen/X86/2007-08-09-IllegalX86-64Asm.ll
+++ b/llvm/test/CodeGen/X86/2007-08-09-IllegalX86-64Asm.ll
@@ -77,7 +77,7 @@ define ptr @ubyte_divmod(ptr %a, ptr %b) {
; CHECK-NEXT: je LBB0_11
; CHECK-NEXT: ## %bb.7: ## %cond_false.i
; CHECK-NEXT: movzbl {{[0-9]+}}(%rsp), %esi
-; CHECK-NEXT: movzbl %sil, %ecx
+; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %ecx, %eax
; CHECK-NEXT: divb %dl
; CHECK-NEXT: movl %eax, %r15d
diff --git a/llvm/test/CodeGen/X86/GlobalISel/callingconv.ll b/llvm/test/CodeGen/X86/GlobalISel/callingconv.ll
index ab8880734afe0..ca70f10b18b41 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/callingconv.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/callingconv.ll
@@ -324,7 +324,7 @@ define void @test_abi_exts_call(ptr %addr) {
; X32-NEXT: .cfi_offset %ebx, -8
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
; X32-NEXT: movzbl (%eax), %ebx
-; X32-NEXT: movzbl %bl, %esi
+; X32-NEXT: movl %ebx, %esi
; X32-NEXT: movl %esi, (%esp)
; X32-NEXT: calll take_char
; X32-NEXT: movsbl %bl, %eax
@@ -346,7 +346,7 @@ define void @test_abi_exts_call(ptr %addr) {
; X64-NEXT: .cfi_def_cfa_offset 16
; X64-NEXT: .cfi_offset %rbx, -16
; X64-NEXT: movzbl (%rdi), %eax
-; X64-NEXT: movzbl %al, %ebx
+; X64-NEXT: movl %eax, %ebx
; X64-NEXT: movl %ebx, %edi
; X64-NEXT: callq take_char
; X64-NEXT: movsbl %bl, %edi
diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll b/llvm/test/CodeGen/X86/atomic-load-store.ll
index 7cfe7af47748a..fca0ba894016f 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -76,7 +76,6 @@ define <1 x i32> @atomic_vec1_i8_zext(ptr %x) {
; CHECK-O3-LABEL: atomic_vec1_i8_zext:
; CHECK-O3: # %bb.0:
; CHECK-O3-NEXT: movzbl (%rdi), %eax
-; CHECK-O3-NEXT: movzbl %al, %eax
; CHECK-O3-NEXT: retq
;
; CHECK-O0-LABEL: atomic_vec1_i8_zext:
diff --git a/llvm/test/CodeGen/X86/fixup-bw-eliminate-redundant-zext.mir b/llvm/test/CodeGen/X86/fixup-bw-eliminate-redundant-zext.mir
new file mode 100644
index 0000000000000..f1f64b38a15bb
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fixup-bw-eliminate-redundant-zext.mir
@@ -0,0 +1,157 @@
+# RUN: llc -mtriple=x86_64-- -run-pass x86-fixup-bw-insts -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=x86_64-- -run-pass x86-fixup-bw-insts -verify-machineinstrs -fixup-bw-eliminate-redundant-zext=0 %s -o - | FileCheck %s --check-prefix=DISABLED
+
+--- |
+ define i32 @same_block(ptr %p) { ret i32 0 }
+ define i32 @across_blocks(ptr %p) { ret i32 0 }
+ define i32 @into_copy(ptr %p) { ret i32 0 }
+ define i32 @clobbered_super_reg(ptr %p) { ret i32 0 }
+ define i32 @high_byte_source(ptr %p) { ret i32 0 }
+ define i32 @word_from_byte(ptr %p) { ret i32 0 }
+ define i32 @byte_from_word(ptr %p) { ret i32 0 }
+...
+
+---
+# The load already zero extends $r12d, so the extend below it is a no-op.
+# CHECK-LABEL: name: same_block
+# CHECK: $r12d = MOVZX32rm8
+# CHECK-NEXT: CMP32ri renamable $r12d, 13
+#
+# DISABLED-LABEL: name: same_block
+# DISABLED: $r12d = MOVZX32rm8
+# DISABLED-NEXT: renamable $r12d = MOVZX32rr8 killed renamable $r12b
+name: same_block
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $rdi
+
+ $r12d = MOVZX32rm8 killed renamable $rdi, 1, $noreg, 0, $noreg
+ renamable $r12d = MOVZX32rr8 killed renamable $r12b
+ CMP32ri renamable $r12d, 13, implicit-def $eflags
+ RET64 $r12d
+...
+
+---
+# The analysis is block local, so an extend in a successor is left alone even
+# though the only predecessor zero extends the value. Removing it would mean
+# making $r9d live in to bb.1, which so far only needed $r9b.
+# CHECK-LABEL: name: across_blocks
+# CHECK: $r9d = MOVZX32rm8
+# CHECK: bb.1:
+# CHECK: liveins: $r9b{{$}}
+# CHECK: renamable $r9d = MOVZX32rr8 killed renamable $r9b
+name: across_blocks
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.1, %bb.2
+ liveins: $rdi
+
+ $r9d = MOVZX32rm8 killed renamable $rdi, 1, $noreg, 0, $noreg
+ CMP8ri renamable $r9b, 10, implicit-def $eflags
+ JCC_1 %bb.2, 4, implicit killed $eflags
+
+ bb.1:
+ successors: %bb.2
+ liveins: $r9b
+
+ renamable $r9d = MOVZX32rr8 killed renamable $r9b
+ CMP32ri renamable $r9d, 13, implicit-def $eflags
+
+ bb.2:
+ liveins: $r9d
+
+ RET64 $r9d
+...
+
+---
+# When the extend moves the value to a different register the move is still
+# needed, but it can be done 32 bits at a time.
+# CHECK-LABEL: name: into_copy
+# CHECK: $eax = MOVZX32rm8
+# CHECK-NEXT: $ecx = MOV32rr $eax
+#
+# DISABLED-LABEL: name: into_copy
+# DISABLED: $eax = MOVZX32rm8
+# DISABLED-NEXT: renamable $ecx = MOVZX32rr8 renamable $al
+name: into_copy
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $rdi
+
+ $eax = MOVZX32rm8 killed renamable $rdi, 1, $noreg, 0, $noreg
+ renamable $ecx = MOVZX32rr8 renamable $al
+ RET64 $eax, $ecx
+...
+
+---
+# The add writes bits that the load had zeroed, so the extend is needed.
+# CHECK-LABEL: name: clobbered_super_reg
+# CHECK: renamable $r12d = MOVZX32rr8 killed renamable $r12b
+name: clobbered_super_reg
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $rdi
+
+ $r12d = MOVZX32rm8 killed renamable $rdi, 1, $noreg, 0, $noreg
+ renamable $r12d = ADD32ri killed renamable $r12d, 65536, implicit-def $eflags
+ renamable $r12d = MOVZX32rr8 killed renamable $r12b
+ RET64 $r12d
+...
+
+---
+# Knowing that $eax is in [0, 0xFF] says that $ah is zero, not that the extend
+# leaves $eax alone, so this one has to stay.
+# CHECK-LABEL: name: high_byte_source
+# CHECK: renamable $eax = MOVZX32rr8 killed renamable $ah
+name: high_byte_source
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $rdi
+
+ $eax = MOVZX32rm8 killed renamable $rdi, 1, $noreg, 0, $noreg
+ renamable $eax = MOVZX32rr8 killed renamable $ah
+ RET64 $eax
+...
+
+---
+# A value in [0, 0xFF] is also in [0, 0xFFFF], so extending it from its low
+# word does nothing either.
+# CHECK-LABEL: name: word_from_byte
+# CHECK: $eax = MOVZX32rm8
+# CHECK-NEXT: CMP32ri renamable $eax, 13
+#
+# DISABLED-LABEL: name: word_from_byte
+# DISABLED: $eax = MOVZX32rm8
+# DISABLED-NEXT: renamable $eax = MOVZX32rr16 killed renamable $ax
+name: word_from_byte
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $rdi
+
+ $eax = MOVZX32rm8 killed renamable $rdi, 1, $noreg, 0, $noreg
+ renamable $eax = MOVZX32rr16 killed renamable $ax
+ CMP32ri renamable $eax, 13, implicit-def $eflags
+ RET64 $eax
+...
+
+---
+# The other way round does not hold: 0x1234 is in [0, 0xFFFF] but extending
+# it from its low byte gives 0x34, so this extend has to stay.
+# CHECK-LABEL: name: byte_from_word
+# CHECK: renamable $eax = MOVZX32rr8 killed renamable $al
+name: byte_from_word
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $rdi
+
+ $eax = MOVZX32rm16 killed renamable $rdi, 1, $noreg, 0, $noreg
+ renamable $eax = MOVZX32rr8 killed renamable $al
+ RET64 $eax
+...
diff --git a/llvm/test/CodeGen/X86/isel-select-cmov.ll b/llvm/test/CodeGen/X86/isel-select-cmov.ll
index 6ced7f45b6233..a9a43a1663bc1 100644
--- a/llvm/test/CodeGen/X86/isel-select-cmov.ll
+++ b/llvm/test/CodeGen/X86/isel-select-cmov.ll
@@ -73,11 +73,9 @@ define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b
; FAST-X86-NEXT: jne LBB0_1
; FAST-X86-NEXT: ## %bb.2:
; FAST-X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
-; FAST-X86-NEXT: movzbl %al, %eax
; FAST-X86-NEXT: retl
; FAST-X86-NEXT: LBB0_1:
; FAST-X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
-; FAST-X86-NEXT: movzbl %al, %eax
; FAST-X86-NEXT: retl
;
; FAST-X86-CMOV-LABEL: select_cmov_i8:
@@ -86,11 +84,9 @@ define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b
; FAST-X86-CMOV-NEXT: jne LBB0_1
; FAST-X86-CMOV-NEXT: ## %bb.2:
; FAST-X86-CMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax
-; FAST-X86-CMOV-NEXT: movzbl %al, %eax
; FAST-X86-CMOV-NEXT: retl
; FAST-X86-CMOV-NEXT: LBB0_1:
; FAST-X86-CMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax
-; FAST-X86-CMOV-NEXT: movzbl %al, %eax
; FAST-X86-CMOV-NEXT: retl
;
; GISEL-X86-LABEL: select_cmov_i8:
@@ -181,11 +177,9 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex
; FAST-X86-NEXT: jne LBB1_1
; FAST-X86-NEXT: ## %bb.2:
; FAST-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
-; FAST-X86-NEXT: movzwl %ax, %eax
; FAST-X86-NEXT: retl
; FAST-X86-NEXT: LBB1_1:
; FAST-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
-; FAST-X86-NEXT: movzwl %ax, %eax
; FAST-X86-NEXT: retl
;
; FAST-X86-CMOV-LABEL: select_cmov_i16:
diff --git a/llvm/test/CodeGen/X86/isel-udiv.ll b/llvm/test/CodeGen/X86/isel-udiv.ll
index b123b3c7780fa..f96a12c2fafd0 100644
--- a/llvm/test/CodeGen/X86/isel-udiv.ll
+++ b/llvm/test/CodeGen/X86/isel-udiv.ll
@@ -22,7 +22,6 @@ define i8 @test_udiv_i8(i8 %arg1, i8 %arg2) nounwind {
; GISEL-X86-LABEL: test_udiv_i8:
; GISEL-X86: # %bb.0:
; GISEL-X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
-; GISEL-X86-NEXT: movzbl %al, %eax
; GISEL-X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; GISEL-X86-NEXT: divb %cl
; GISEL-X86-NEXT: retl
diff --git a/llvm/test/CodeGen/X86/isel-urem.ll b/llvm/test/CodeGen/X86/isel-urem.ll
index 386f08151ad9c..5dd901fe8daa6 100644
--- a/llvm/test/CodeGen/X86/isel-urem.ll
+++ b/llvm/test/CodeGen/X86/isel-urem.ll
@@ -49,7 +49,6 @@ define i8 @test_urem_i8(i8 %arg1, i8 %arg2) nounwind {
; GISEL-X86-LABEL: test_urem_i8:
; GISEL-X86: # %bb.0:
; GISEL-X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
-; GISEL-X86-NEXT: movzbl %al, %eax
; GISEL-X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; GISEL-X86-NEXT: divb %cl
; GISEL-X86-NEXT: movb %ah, %al
diff --git a/llvm/test/CodeGen/X86/load-local-v4i5.ll b/llvm/test/CodeGen/X86/load-local-v4i5.ll
index 1d119b1dfefc2..d470c590a1ac7 100644
--- a/llvm/test/CodeGen/X86/load-local-v4i5.ll
+++ b/llvm/test/CodeGen/X86/load-local-v4i5.ll
@@ -11,7 +11,7 @@ define void @_start() {
; CHECK-NEXT: movzbl -9(%rsp), %ecx
; CHECK-NEXT: movzbl -10(%rsp), %edx
; CHECK-NEXT: movzbl -11(%rsp), %esi
-; CHECK-NEXT: movzbl %cl, %edi
+; CHECK-NEXT: movl %ecx, %edi
; CHECK-NEXT: shrb %cl
; CHECK-NEXT: movb %cl, -2(%rsp)
; CHECK-NEXT: andl $31, %eax
diff --git a/llvm/test/CodeGen/X86/popcnt.ll b/llvm/test/CodeGen/X86/popcnt.ll
index 3004b8b72fcc5..0e3f907e8d5be 100644
--- a/llvm/test/CodeGen/X86/popcnt.ll
+++ b/llvm/test/CodeGen/X86/popcnt.ll
@@ -1890,7 +1890,6 @@ define i32 @popcount_i16_zext(i16 zeroext %x) {
; X64-NDD-NEXT: movzbl %ah, %ecx
; X64-NDD-NEXT: addw %cx, %ax
; X64-NDD-NEXT: movzbl %al, %eax
-; X64-NDD-NEXT: movzwl %ax, %eax
; X64-NDD-NEXT: retq
%cnt = tail call i16 @llvm.ctpop.i16(i16 %x)
%z = zext i16 %cnt to i32
diff --git a/llvm/test/CodeGen/X86/pr15267.ll b/llvm/test/CodeGen/X86/pr15267.ll
index 5083eac71dce0..a8c4b9eb6370d 100644
--- a/llvm/test/CodeGen/X86/pr15267.ll
+++ b/llvm/test/CodeGen/X86/pr15267.ll
@@ -50,7 +50,7 @@ define <4 x i64> @test3(ptr %in) nounwind {
; CHECK-LABEL: test3:
; CHECK: # %bb.0:
; CHECK-NEXT: movzbl (%rdi), %eax
-; CHECK-NEXT: movzbl %al, %ecx
+; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: shrb %al
; CHECK-NEXT: movzbl %al, %eax
; CHECK-NEXT: andl $1, %eax
diff --git a/llvm/test/CodeGen/X86/pr38539.ll b/llvm/test/CodeGen/X86/pr38539.ll
index eecd15dd2afe9..6cd27afe75842 100644
--- a/llvm/test/CodeGen/X86/pr38539.ll
+++ b/llvm/test/CodeGen/X86/pr38539.ll
@@ -28,7 +28,6 @@ define void @f() nounwind {
; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
; X86-NEXT: movzbl (%eax), %eax
; X86-NEXT: movzbl (%eax), %ecx
-; X86-NEXT: movzbl %al, %eax
; X86-NEXT: movb %cl, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
; X86-NEXT: divb %cl
; X86-NEXT: movl %edi, %eax
diff --git a/llvm/test/CodeGen/X86/promote-assert-zext.ll b/llvm/test/CodeGen/X86/promote-assert-zext.ll
index d9e2585262ab7..feec7de48bd19 100644
--- a/llvm/test/CodeGen/X86/promote-assert-zext.ll
+++ b/llvm/test/CodeGen/X86/promote-assert-zext.ll
@@ -1,6 +1,11 @@
-; RUN: llc < %s | FileCheck %s
+; RUN: llc < %s -fixup-bw-eliminate-redundant-zext=0 | FileCheck %s
; rdar://8051990
+; The zero-extend below is removed later on, by X86FixupBWInsts, which can
+; prove from the widened load that it is a no-op. That is disabled here so
+; that this keeps testing what it was written to test, that ISel does not
+; remove it: without the extra instruction the two outcomes are the same.
+
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin11"
diff --git a/llvm/test/CodeGen/X86/vector-compress.ll b/llvm/test/CodeGen/X86/vector-compress.ll
index 018c3d36ee60d..a055319f346ef 100644
--- a/llvm/test/CodeGen/X86/vector-compress.ll
+++ b/llvm/test/CodeGen/X86/vector-compress.ll
@@ -2236,7 +2236,7 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: vpextrb $5, %xmm0, (%rsp,%rax)
; AVX2-NEXT: andl $1, %r9d
; AVX2-NEXT: addq %r8, %r9
-; AVX2-NEXT: movzbl %r10b, %eax
+; AVX2-NEXT: movl %r10d, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %r9, %rax
; AVX2-NEXT: # kill: def $r9d killed $r9d killed $r9 def $r9
@@ -2245,10 +2245,10 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: movl %eax, %ecx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $7, %xmm0, (%rsp,%rcx)
-; AVX2-NEXT: movzbl %r11b, %ecx
+; AVX2-NEXT: movl %r11d, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
-; AVX2-NEXT: movzbl %bl, %eax
+; AVX2-NEXT: movl %ebx, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2257,10 +2257,10 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: movl %eax, %ecx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $9, %xmm0, (%rsp,%rcx)
-; AVX2-NEXT: movzbl %r14b, %ecx
+; AVX2-NEXT: movl %r14d, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
-; AVX2-NEXT: movzbl %r15b, %eax
+; AVX2-NEXT: movl %r15d, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2269,11 +2269,10 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: movl %eax, %ecx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $11, %xmm0, (%rsp,%rcx)
-; AVX2-NEXT: movzbl %r12b, %ecx
+; AVX2-NEXT: movl %r12d, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: movzbl 64(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2283,18 +2282,15 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $13, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 72(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: movzbl 80(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $14, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 88(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2305,11 +2301,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0
; AVX2-NEXT: vpextrb $0, %xmm0, (%rsp,%rax)
; AVX2-NEXT: movzbl 96(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 104(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2319,11 +2313,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $2, %xmm0, (%rsp,%rax)
; AVX2-NEXT: movzbl 112(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 120(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2333,11 +2325,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $4, %xmm0, (%rsp,%rax)
; AVX2-NEXT: movzbl 128(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 136(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2347,11 +2337,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $6, %xmm0, (%rsp,%rax)
; AVX2-NEXT: movzbl 144(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 152(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2361,11 +2349,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $8, %xmm0, (%rsp,%rax)
; AVX2-NEXT: movzbl 160(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 168(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2375,11 +2361,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $10, %xmm0, (%rsp,%rax)
; AVX2-NEXT: movzbl 176(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 184(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2389,11 +2373,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $12, %xmm0, (%rsp,%rax)
; AVX2-NEXT: movzbl 192(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 200(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2403,11 +2385,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $14, %xmm0, (%rsp,%rax)
; AVX2-NEXT: movzbl 208(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 216(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2417,11 +2397,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $0, %xmm1, (%rsp,%rax)
; AVX2-NEXT: movzbl 224(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 232(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2431,11 +2409,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $2, %xmm1, (%rsp,%rax)
; AVX2-NEXT: movzbl 240(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 248(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2445,11 +2421,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $4, %xmm1, (%rsp,%rax)
; AVX2-NEXT: movzbl 256(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 264(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2459,11 +2433,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $6, %xmm1, (%rsp,%rax)
; AVX2-NEXT: movzbl 272(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 280(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2473,11 +2445,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $8, %xmm1, (%rsp,%rax)
; AVX2-NEXT: movzbl 288(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 296(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2487,11 +2457,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $10, %xmm1, (%rsp,%rax)
; AVX2-NEXT: movzbl 304(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 312(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2501,11 +2469,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $12, %xmm1, (%rsp,%rax)
; AVX2-NEXT: movzbl 320(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 328(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
@@ -2515,18 +2481,15 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $14, %xmm1, (%rsp,%rax)
; AVX2-NEXT: movzbl 336(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: movzbl 344(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: # kill: def $eax killed $eax killed $rax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vpextrb $15, %xmm1, (%rsp,%rax)
; AVX2-NEXT: movzbl 352(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2537,11 +2500,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $1, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 360(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: movzbl 368(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2551,11 +2512,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $3, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 376(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: movzbl 384(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2565,11 +2524,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $5, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 392(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: movzbl 400(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2579,11 +2536,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $7, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 408(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: movzbl 416(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2593,11 +2548,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $9, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 424(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: movzbl 432(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2607,11 +2560,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $11, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 440(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: movzbl 448(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2621,11 +2572,9 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $13, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 456(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addq %rax, %rcx
; AVX2-NEXT: movzbl 464(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addq %rcx, %rax
; AVX2-NEXT: # kill: def $ecx killed $ecx killed $rcx def $rcx
@@ -2635,7 +2584,6 @@ define <64 x i8> @test_compress_v64i8(<64 x i8> %vec, <64 x i1> %mask, <64 x i8>
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vpextrb $15, %xmm0, (%rsp,%rcx)
; AVX2-NEXT: movzbl 472(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: vpextrb $15, %xmm0, %edx
; AVX2-NEXT: addq %rax, %rcx
@@ -4009,51 +3957,43 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: addl %r8d, %r9d
; AVX2-NEXT: vextractps $1, %xmm0, (%rsp,%r9,4)
; AVX2-NEXT: movzbl 16(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %r9d, %eax
; AVX2-NEXT: vextractps $2, %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 24(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: movl %ecx, %eax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $3, %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 32(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: movzbl 40(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vmovss %xmm1, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 48(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm1, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 56(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $2, %xmm1, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 64(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $3, %xmm1, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 72(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4061,14 +4001,12 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: vextractf128 $1, %ymm1, %xmm0
; AVX2-NEXT: vmovss %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 80(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm0, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 88(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4078,39 +4016,33 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $3, %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 96(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: movzbl 104(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vmovss %xmm2, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 112(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm2, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 120(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $2, %xmm2, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 128(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $3, %xmm2, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 136(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4118,14 +4050,12 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: vextractf128 $1, %ymm2, %xmm0
; AVX2-NEXT: vmovss %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 144(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm0, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 152(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4135,39 +4065,33 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $3, %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 160(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: movzbl 168(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vmovss %xmm3, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 176(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm3, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 184(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $2, %xmm3, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 192(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $3, %xmm3, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 200(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4175,14 +4099,12 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: vextractf128 $1, %ymm3, %xmm0
; AVX2-NEXT: vmovss %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 208(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm0, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 216(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4192,39 +4114,33 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $3, %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 224(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: movzbl 232(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vmovss %xmm4, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 240(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm4, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 248(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $2, %xmm4, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 256(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $3, %xmm4, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 264(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4232,14 +4148,12 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: vextractf128 $1, %ymm4, %xmm0
; AVX2-NEXT: vmovss %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 272(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm0, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 280(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4249,39 +4163,33 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $3, %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 288(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: movzbl 296(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vmovss %xmm5, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 304(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm5, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 312(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $2, %xmm5, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 320(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $3, %xmm5, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 328(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4289,14 +4197,12 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: vextractf128 $1, %ymm5, %xmm0
; AVX2-NEXT: vmovss %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 336(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm0, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 344(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4306,39 +4212,33 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $3, %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 352(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: movzbl 360(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vmovss %xmm6, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 368(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm6, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 376(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
; AVX2-NEXT: andl $63, %eax
; AVX2-NEXT: vextractps $2, %xmm6, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 384(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $3, %xmm6, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 392(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4346,14 +4246,12 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: vextractf128 $1, %ymm6, %xmm0
; AVX2-NEXT: vmovss %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movzbl 400(%rbp), %eax
-; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
; AVX2-NEXT: addl %ecx, %eax
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm0, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 408(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %eax, %ecx
; AVX2-NEXT: # kill: def $eax killed $eax def $rax
@@ -4364,39 +4262,33 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: vextractps $3, %xmm0, (%rsp,%rax,4)
; AVX2-NEXT: movq %rdi, %rax
; AVX2-NEXT: movzbl 416(%rbp), %edx
-; AVX2-NEXT: movzbl %dl, %edx
; AVX2-NEXT: andl $1, %edx
; AVX2-NEXT: addl %ecx, %edx
; AVX2-NEXT: movzbl 424(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %edx, %ecx
; AVX2-NEXT: # kill: def $edx killed $edx def $rdx
; AVX2-NEXT: andl $63, %edx
; AVX2-NEXT: vmovss %xmm7, (%rsp,%rdx,4)
; AVX2-NEXT: movzbl 432(%rbp), %edx
-; AVX2-NEXT: movzbl %dl, %edx
; AVX2-NEXT: andl $1, %edx
; AVX2-NEXT: addl %ecx, %edx
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm7, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 440(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %edx, %ecx
; AVX2-NEXT: # kill: def $edx killed $edx def $rdx
; AVX2-NEXT: andl $63, %edx
; AVX2-NEXT: vextractps $2, %xmm7, (%rsp,%rdx,4)
; AVX2-NEXT: movzbl 448(%rbp), %edx
-; AVX2-NEXT: movzbl %dl, %edx
; AVX2-NEXT: andl $1, %edx
; AVX2-NEXT: addl %ecx, %edx
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $3, %xmm7, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 456(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %edx, %ecx
; AVX2-NEXT: # kill: def $edx killed $edx def $rdx
@@ -4404,14 +4296,12 @@ define <64 x i32> @test_compress_large(<64 x i1> %mask, <64 x i32> %vec, <64 x i
; AVX2-NEXT: vextractf128 $1, %ymm7, %xmm0
; AVX2-NEXT: vmovss %xmm0, (%rsp,%rdx,4)
; AVX2-NEXT: movzbl 464(%rbp), %edx
-; AVX2-NEXT: movzbl %dl, %edx
; AVX2-NEXT: andl $1, %edx
; AVX2-NEXT: addl %ecx, %edx
; AVX2-NEXT: # kill: def $ecx killed $ecx def $rcx
; AVX2-NEXT: andl $63, %ecx
; AVX2-NEXT: vextractps $1, %xmm0, (%rsp,%rcx,4)
; AVX2-NEXT: movzbl 472(%rbp), %ecx
-; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: andl $1, %ecx
; AVX2-NEXT: addl %edx, %ecx
; AVX2-NEXT: # kill: def $edx killed $edx def $rdx
diff --git a/llvm/test/CodeGen/X86/vector-sext.ll b/llvm/test/CodeGen/X86/vector-sext.ll
index 95f9b71d70376..f742dfac9290f 100644
--- a/llvm/test/CodeGen/X86/vector-sext.ll
+++ b/llvm/test/CodeGen/X86/vector-sext.ll
@@ -1343,7 +1343,7 @@ define <2 x i64> @load_sext_2i1_to_2i64(ptr%ptr) {
; SSE-LABEL: load_sext_2i1_to_2i64:
; SSE: # %bb.0: # %entry
; SSE-NEXT: movzbl (%rdi), %eax
-; SSE-NEXT: movzbl %al, %ecx
+; SSE-NEXT: movl %eax, %ecx
; SSE-NEXT: shrb %al
; SSE-NEXT: movzbl %al, %eax
; SSE-NEXT: negq %rax
@@ -1357,7 +1357,7 @@ define <2 x i64> @load_sext_2i1_to_2i64(ptr%ptr) {
; AVX1-LABEL: load_sext_2i1_to_2i64:
; AVX1: # %bb.0: # %entry
; AVX1-NEXT: movzbl (%rdi), %eax
-; AVX1-NEXT: movzbl %al, %ecx
+; AVX1-NEXT: movl %eax, %ecx
; AVX1-NEXT: shrb %al
; AVX1-NEXT: movzbl %al, %eax
; AVX1-NEXT: negq %rax
@@ -1371,7 +1371,7 @@ define <2 x i64> @load_sext_2i1_to_2i64(ptr%ptr) {
; AVX2-LABEL: load_sext_2i1_to_2i64:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: movzbl (%rdi), %eax
-; AVX2-NEXT: movzbl %al, %ecx
+; AVX2-NEXT: movl %eax, %ecx
; AVX2-NEXT: shrb %al
; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: negq %rax
@@ -1404,7 +1404,7 @@ define <2 x i64> @load_sext_2i1_to_2i64(ptr%ptr) {
; X86-SSE2: # %bb.0: # %entry
; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-SSE2-NEXT: movzbl (%eax), %eax
-; X86-SSE2-NEXT: movzbl %al, %ecx
+; X86-SSE2-NEXT: movl %eax, %ecx
; X86-SSE2-NEXT: shrb %al
; X86-SSE2-NEXT: movzbl %al, %eax
; X86-SSE2-NEXT: negl %eax
@@ -1421,7 +1421,7 @@ define <2 x i64> @load_sext_2i1_to_2i64(ptr%ptr) {
; X86-SSE41: # %bb.0: # %entry
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-SSE41-NEXT: movzbl (%eax), %eax
-; X86-SSE41-NEXT: movzbl %al, %ecx
+; X86-SSE41-NEXT: movl %eax, %ecx
; X86-SSE41-NEXT: andl $1, %ecx
; X86-SSE41-NEXT: negl %ecx
; X86-SSE41-NEXT: movd %ecx, %xmm0
@@ -1506,7 +1506,7 @@ define <4 x i32> @load_sext_4i1_to_4i32(ptr%ptr) {
; SSE2-NEXT: movzbl %cl, %ecx
; SSE2-NEXT: negl %ecx
; SSE2-NEXT: movd %ecx, %xmm0
-; SSE2-NEXT: movzbl %al, %ecx
+; SSE2-NEXT: movl %eax, %ecx
; SSE2-NEXT: shrb $2, %al
; SSE2-NEXT: movzbl %al, %eax
; SSE2-NEXT: andl $1, %eax
@@ -1534,7 +1534,7 @@ define <4 x i32> @load_sext_4i1_to_4i32(ptr%ptr) {
; SSSE3-NEXT: movzbl %cl, %ecx
; SSSE3-NEXT: negl %ecx
; SSSE3-NEXT: movd %ecx, %xmm0
-; SSSE3-NEXT: movzbl %al, %ecx
+; SSSE3-NEXT: movl %eax, %ecx
; SSSE3-NEXT: shrb $2, %al
; SSSE3-NEXT: movzbl %al, %eax
; SSSE3-NEXT: andl $1, %eax
@@ -1557,7 +1557,7 @@ define <4 x i32> @load_sext_4i1_to_4i32(ptr%ptr) {
; SSE41-LABEL: load_sext_4i1_to_4i32:
; SSE41: # %bb.0: # %entry
; SSE41-NEXT: movzbl (%rdi), %eax
-; SSE41-NEXT: movzbl %al, %ecx
+; SSE41-NEXT: movl %eax, %ecx
; SSE41-NEXT: shrb %al
; SSE41-NEXT: movzbl %al, %eax
; SSE41-NEXT: andl $1, %eax
@@ -1582,7 +1582,7 @@ define <4 x i32> @load_sext_4i1_to_4i32(ptr%ptr) {
; AVX1-LABEL: load_sext_4i1_to_4i32:
; AVX1: # %bb.0: # %entry
; AVX1-NEXT: movzbl (%rdi), %eax
-; AVX1-NEXT: movzbl %al, %ecx
+; AVX1-NEXT: movl %eax, %ecx
; AVX1-NEXT: shrb %al
; AVX1-NEXT: movzbl %al, %eax
; AVX1-NEXT: andl $1, %eax
@@ -1607,7 +1607,7 @@ define <4 x i32> @load_sext_4i1_to_4i32(ptr%ptr) {
; AVX2-LABEL: load_sext_4i1_to_4i32:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: movzbl (%rdi), %eax
-; AVX2-NEXT: movzbl %al, %ecx
+; AVX2-NEXT: movl %eax, %ecx
; AVX2-NEXT: shrb %al
; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
@@ -1663,7 +1663,7 @@ define <4 x i32> @load_sext_4i1_to_4i32(ptr%ptr) {
; X86-SSE2-NEXT: negl %ecx
; X86-SSE2-NEXT: movd %ecx, %xmm1
; X86-SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; X86-SSE2-NEXT: movzbl %al, %ecx
+; X86-SSE2-NEXT: movl %eax, %ecx
; X86-SSE2-NEXT: andl $1, %ecx
; X86-SSE2-NEXT: negl %ecx
; X86-SSE2-NEXT: movd %ecx, %xmm0
@@ -1685,7 +1685,7 @@ define <4 x i32> @load_sext_4i1_to_4i32(ptr%ptr) {
; X86-SSE41-NEXT: movzbl %cl, %ecx
; X86-SSE41-NEXT: andl $1, %ecx
; X86-SSE41-NEXT: negl %ecx
-; X86-SSE41-NEXT: movzbl %al, %edx
+; X86-SSE41-NEXT: movl %eax, %edx
; X86-SSE41-NEXT: andl $1, %edx
; X86-SSE41-NEXT: negl %edx
; X86-SSE41-NEXT: movd %edx, %xmm0
@@ -1842,7 +1842,7 @@ define <4 x i64> @load_sext_4i1_to_4i64(ptr%ptr) {
; AVX1-LABEL: load_sext_4i1_to_4i64:
; AVX1: # %bb.0: # %entry
; AVX1-NEXT: movzbl (%rdi), %eax
-; AVX1-NEXT: movzbl %al, %ecx
+; AVX1-NEXT: movl %eax, %ecx
; AVX1-NEXT: shrb %al
; AVX1-NEXT: movzbl %al, %eax
; AVX1-NEXT: andl $1, %eax
@@ -1875,7 +1875,7 @@ define <4 x i64> @load_sext_4i1_to_4i64(ptr%ptr) {
; AVX2-NEXT: movzbl %cl, %ecx
; AVX2-NEXT: negq %rcx
; AVX2-NEXT: vmovq %rcx, %xmm0
-; AVX2-NEXT: movzbl %al, %ecx
+; AVX2-NEXT: movl %eax, %ecx
; AVX2-NEXT: shrb $2, %al
; AVX2-NEXT: movzbl %al, %eax
; AVX2-NEXT: andl $1, %eax
>From b47e40dccf5f45c39cb1e40597383fc2937b210c Mon Sep 17 00:00:00 2001
From: Jan Jecmen <jjecmen at azul.com>
Date: Mon, 24 Aug 2026 08:10:05 +0000
Subject: [PATCH 2/3] Address review and clang-format
---
llvm/lib/Target/X86/X86FixupBWInsts.cpp | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/X86/X86FixupBWInsts.cpp b/llvm/lib/Target/X86/X86FixupBWInsts.cpp
index d07b7c64693f5..b9391a4f7cdde 100644
--- a/llvm/lib/Target/X86/X86FixupBWInsts.cpp
+++ b/llvm/lib/Target/X86/X86FixupBWInsts.cpp
@@ -78,11 +78,6 @@ static cl::opt<bool>
cl::desc("Change byte and word instructions to larger sizes"),
cl::init(true), cl::Hidden);
-static cl::opt<bool> EliminateRedundantZExts(
- "fixup-bw-eliminate-redundant-zext",
- cl::desc("Remove zero extends of already zero extended values"),
- cl::init(true), cl::Hidden);
-
namespace {
class X86FixupBWInstImpl {
public:
@@ -122,7 +117,7 @@ class X86FixupBWInstImpl {
MachineInstr *tryReplaceInstr(MachineInstr *MI, MachineBasicBlock &MBB) const;
/// Remove the zero extends in \p MBB of values that an earlier instruction
- /// in the same block (widened by this pass) has already zero extended.
+ /// in the same block (widened by this pass) has already zero extended.
void eliminateRedundantZeroExtends(MachineBasicBlock &MBB);
MachineFunction *MF = nullptr;
@@ -188,11 +183,8 @@ bool X86FixupBWInstImpl::runOnMachineFunction(MachineFunction &MF) {
LLVM_DEBUG(dbgs() << "Start X86FixupBWInsts\n";);
// Process all basic blocks.
- for (auto &MBB : MF) {
+ for (auto &MBB : MF)
processBasicBlock(MF, MBB);
- if (EliminateRedundantZExts)
- eliminateRedundantZeroExtends(MBB);
- }
LLVM_DEBUG(dbgs() << "End X86FixupBWInsts\n";);
@@ -580,6 +572,9 @@ void X86FixupBWInstImpl::processBasicBlock(MachineFunction &MF,
MBB.insert(MI, NewMI);
MBB.erase(MI);
}
+
+ // Finally, clean up any zero extends made redundant by widening.
+ eliminateRedundantZeroExtends(MBB);
}
bool X86FixupBWInstLegacy::runOnMachineFunction(MachineFunction &MF) {
>From 9576a5cd5d4151c6b2b9e99ff17965737d7f89a7 Mon Sep 17 00:00:00 2001
From: Jan Jecmen <jjecmen at azul.com>
Date: Mon, 24 Aug 2026 10:53:35 +0000
Subject: [PATCH 3/3] Update tests after flag removal
---
.../X86/fixup-bw-eliminate-redundant-zext.mir | 13 -------------
llvm/test/CodeGen/X86/promote-assert-zext.ll | 10 +++++-----
2 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/llvm/test/CodeGen/X86/fixup-bw-eliminate-redundant-zext.mir b/llvm/test/CodeGen/X86/fixup-bw-eliminate-redundant-zext.mir
index f1f64b38a15bb..245fdf268c97d 100644
--- a/llvm/test/CodeGen/X86/fixup-bw-eliminate-redundant-zext.mir
+++ b/llvm/test/CodeGen/X86/fixup-bw-eliminate-redundant-zext.mir
@@ -1,5 +1,4 @@
# RUN: llc -mtriple=x86_64-- -run-pass x86-fixup-bw-insts -verify-machineinstrs %s -o - | FileCheck %s
-# RUN: llc -mtriple=x86_64-- -run-pass x86-fixup-bw-insts -verify-machineinstrs -fixup-bw-eliminate-redundant-zext=0 %s -o - | FileCheck %s --check-prefix=DISABLED
--- |
define i32 @same_block(ptr %p) { ret i32 0 }
@@ -16,10 +15,6 @@
# CHECK-LABEL: name: same_block
# CHECK: $r12d = MOVZX32rm8
# CHECK-NEXT: CMP32ri renamable $r12d, 13
-#
-# DISABLED-LABEL: name: same_block
-# DISABLED: $r12d = MOVZX32rm8
-# DISABLED-NEXT: renamable $r12d = MOVZX32rr8 killed renamable $r12b
name: same_block
tracksRegLiveness: true
body: |
@@ -71,10 +66,6 @@ body: |
# CHECK-LABEL: name: into_copy
# CHECK: $eax = MOVZX32rm8
# CHECK-NEXT: $ecx = MOV32rr $eax
-#
-# DISABLED-LABEL: name: into_copy
-# DISABLED: $eax = MOVZX32rm8
-# DISABLED-NEXT: renamable $ecx = MOVZX32rr8 renamable $al
name: into_copy
tracksRegLiveness: true
body: |
@@ -124,10 +115,6 @@ body: |
# CHECK-LABEL: name: word_from_byte
# CHECK: $eax = MOVZX32rm8
# CHECK-NEXT: CMP32ri renamable $eax, 13
-#
-# DISABLED-LABEL: name: word_from_byte
-# DISABLED: $eax = MOVZX32rm8
-# DISABLED-NEXT: renamable $eax = MOVZX32rr16 killed renamable $ax
name: word_from_byte
tracksRegLiveness: true
body: |
diff --git a/llvm/test/CodeGen/X86/promote-assert-zext.ll b/llvm/test/CodeGen/X86/promote-assert-zext.ll
index feec7de48bd19..c78a79e36111f 100644
--- a/llvm/test/CodeGen/X86/promote-assert-zext.ll
+++ b/llvm/test/CodeGen/X86/promote-assert-zext.ll
@@ -1,10 +1,10 @@
-; RUN: llc < %s -fixup-bw-eliminate-redundant-zext=0 | FileCheck %s
+; RUN: llc < %s -fixup-byte-word-insts=0 | FileCheck %s
; rdar://8051990
-; The zero-extend below is removed later on, by X86FixupBWInsts, which can
-; prove from the widened load that it is a no-op. That is disabled here so
-; that this keeps testing what it was written to test, that ISel does not
-; remove it: without the extra instruction the two outcomes are the same.
+; X86FixupBWInsts removes the zero-extend below, having proven it to be a
+; no-op. It is disabled here so that this keeps testing what it was written
+; to test, that ISel does not remove it: without the extra instruction the
+; passing and failing outcomes are indistinguishable.
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin11"
More information about the llvm-commits
mailing list