[llvm] [X86] Remove zero extends made redundant by the byte/word fixup (PR #217923)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 21 11:19:31 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
@llvm/pr-subscribers-backend-x86
Author: Jan Ječmen (JanJecmen)
<details>
<summary>Changes</summary>
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@<!-- -->anthropic.com>
---
Patch is 55.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217923.diff
15 Files Affected:
- (modified) llvm/lib/Target/X86/X86FixupBWInsts.cpp (+111-1)
- (modified) llvm/test/CodeGen/X86/2007-08-09-IllegalX86-64Asm.ll (+1-1)
- (modified) llvm/test/CodeGen/X86/GlobalISel/callingconv.ll (+2-2)
- (modified) llvm/test/CodeGen/X86/atomic-load-store.ll (-1)
- (added) llvm/test/CodeGen/X86/fixup-bw-eliminate-redundant-zext.mir (+157)
- (modified) llvm/test/CodeGen/X86/isel-select-cmov.ll (-6)
- (modified) llvm/test/CodeGen/X86/isel-udiv.ll (-1)
- (modified) llvm/test/CodeGen/X86/isel-urem.ll (-1)
- (modified) llvm/test/CodeGen/X86/load-local-v4i5.ll (+1-1)
- (modified) llvm/test/CodeGen/X86/popcnt.ll (-1)
- (modified) llvm/test/CodeGen/X86/pr15267.ll (+1-1)
- (modified) llvm/test/CodeGen/X86/pr38539.ll (-1)
- (modified) llvm/test/CodeGen/X86/promote-assert-zext.ll (+6-1)
- (modified) llvm/test/CodeGen/X86/vector-compress.ll (+6-116)
- (modified) llvm/test/CodeGen/X86/vector-sext.ll (+14-14)
``````````diff
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-NEX...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/217923
More information about the llvm-commits
mailing list