[llvm] [CodeGenPrepare] Reuse free wider zero extensions (PR #228750)

Dávid Bolvanský via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 3 10:54:23 PDT 2026


https://github.com/davidbolvansky updated https://github.com/llvm/llvm-project/pull/228750

>From 4911096fd3a1b3126fb0d1f59902552333c2bbaf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1vid=20Bolvansk=C3=BD?= <david.bolvansky at gmail.com>
Date: Sat, 3 Oct 2026 19:41:34 +0200
Subject: [PATCH 1/2] [CodeGenPrepare] Reuse free wider extensions without
 truncating

Reuse an existing extension for a wider extension of the same kind when the target considers it free. Avoid hiding extending-load promotion behind a truncate/re-extend pair.

Assisted-by: OpenAI Codex
---
 llvm/lib/CodeGen/CodeGenPrepare.cpp           |  16 ++
 .../CodeGenPrepare/reuse-extension.ll         | 228 ++++++++++++++++++
 2 files changed, 244 insertions(+)
 create mode 100644 llvm/test/Transforms/CodeGenPrepare/reuse-extension.ll

diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 0b96c77ff33ea..fbb4d3b4e0261 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -7391,6 +7391,22 @@ bool CodeGenPrepare::optimizeExtUses(Instruction *I) {
       continue;
 
     // Both src and def are live in this block. Rewrite the use.
+    // Reuse an extension directly when a wider extension of the same kind is
+    // free for its users.
+    // Going through a truncation instead can hide an extending-load
+    // opportunity.
+    if (I->getOpcode() == User->getOpcode() &&
+        User->getType()->getScalarSizeInBits() >
+            I->getType()->getScalarSizeInBits()) {
+      U = I;
+      if (TLI->isExtFree(User)) {
+        ++NumExtUses;
+        MadeChange = true;
+        continue;
+      }
+      U = Src;
+    }
+
     Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
 
     if (!InsertedTrunc) {
diff --git a/llvm/test/Transforms/CodeGenPrepare/reuse-extension.ll b/llvm/test/Transforms/CodeGenPrepare/reuse-extension.ll
new file mode 100644
index 0000000000000..8484ea8b42f7a
--- /dev/null
+++ b/llvm/test/Transforms/CodeGenPrepare/reuse-extension.ll
@@ -0,0 +1,228 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -mtriple=aarch64 < %s | FileCheck %s --check-prefixes=CHECK,AARCH64
+; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -mtriple=x86_64 < %s | FileCheck %s --check-prefixes=CHECK,X86
+; REQUIRES: aarch64-registered-target, x86-registered-target
+
+; Reusing a free wider extension must not introduce a truncation that
+; prevents CodeGenPrepare from moving the extension to the original load.
+declare void @consume(i32)
+declare void @consume64(i64)
+
+define i64 @zext_i8(ptr %p, ptr %table, i1 %cold) {
+;
+; CHECK-LABEL: @zext_i8(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[V:%.*]] = load i8, ptr [[P:%.*]], align 1
+; CHECK-NEXT:    [[PROMOTED:%.*]] = zext i8 [[V]] to i64
+; CHECK-NEXT:    [[V32:%.*]] = zext i8 [[V]] to i32
+; CHECK-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
+; CHECK:       call:
+; CHECK-NEXT:    call void @consume(i32 [[V32]])
+; CHECK-NEXT:    br label [[JOIN]]
+; CHECK:       join:
+; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[TABLE:%.*]], i64 [[PROMOTED]]
+; CHECK-NEXT:    [[MASK:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    [[SUM:%.*]] = add i32 [[MASK]], [[V32]]
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i32 [[SUM]] to i64
+; CHECK-NEXT:    ret i64 [[RESULT]]
+;
+entry:
+  %v = load i8, ptr %p
+  %v32 = zext i8 %v to i32
+  br i1 %cold, label %call, label %join
+call:
+  call void @consume(i32 %v32)
+  br label %join
+join:
+  %v64 = zext i8 %v to i64
+  %ptr = getelementptr i32, ptr %table, i64 %v64
+  %mask = load i32, ptr %ptr
+  %sum = add i32 %mask, %v32
+  %result = zext i32 %sum to i64
+  ret i64 %result
+}
+
+define i64 @zext_i16(ptr %p, ptr %table, i1 %cold) {
+;
+; CHECK-LABEL: @zext_i16(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[V:%.*]] = load i16, ptr [[P:%.*]], align 2
+; CHECK-NEXT:    [[PROMOTED:%.*]] = zext i16 [[V]] to i64
+; CHECK-NEXT:    [[V32:%.*]] = zext i16 [[V]] to i32
+; CHECK-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
+; CHECK:       call:
+; CHECK-NEXT:    call void @consume(i32 [[V32]])
+; CHECK-NEXT:    br label [[JOIN]]
+; CHECK:       join:
+; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[TABLE:%.*]], i64 [[PROMOTED]]
+; CHECK-NEXT:    [[MASK:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    [[SUM:%.*]] = add i32 [[MASK]], [[V32]]
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i32 [[SUM]] to i64
+; CHECK-NEXT:    ret i64 [[RESULT]]
+;
+entry:
+  %v = load i16, ptr %p
+  %v32 = zext i16 %v to i32
+  br i1 %cold, label %call, label %join
+call:
+  call void @consume(i32 %v32)
+  br label %join
+join:
+  %v64 = zext i16 %v to i64
+  %ptr = getelementptr i32, ptr %table, i64 %v64
+  %mask = load i32, ptr %ptr
+  %sum = add i32 %mask, %v32
+  %result = zext i32 %sum to i64
+  ret i64 %result
+}
+
+define i64 @sext_then_zext(ptr %p, ptr %table, i1 %cold) {
+;
+; CHECK-LABEL: @sext_then_zext(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[V:%.*]] = load i8, ptr [[P:%.*]], align 1
+; CHECK-NEXT:    [[V32:%.*]] = sext i8 [[V]] to i32
+; CHECK-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
+; CHECK:       call:
+; CHECK-NEXT:    call void @consume(i32 [[V32]])
+; CHECK-NEXT:    br label [[JOIN]]
+; CHECK:       join:
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i32 [[V32]] to i8
+; CHECK-NEXT:    [[V64:%.*]] = zext i8 [[TMP0]] to i64
+; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[TABLE:%.*]], i64 [[V64]]
+; CHECK-NEXT:    [[MASK:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    [[SUM:%.*]] = add i32 [[MASK]], [[V32]]
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i32 [[SUM]] to i64
+; CHECK-NEXT:    ret i64 [[RESULT]]
+;
+entry:
+  %v = load i8, ptr %p
+  %v32 = sext i8 %v to i32
+  br i1 %cold, label %call, label %join
+call:
+  call void @consume(i32 %v32)
+  br label %join
+join:
+  %v64 = zext i8 %v to i64
+  %ptr = getelementptr i32, ptr %table, i64 %v64
+  %mask = load i32, ptr %ptr
+  %sum = add i32 %mask, %v32
+  %result = zext i32 %sum to i64
+  ret i64 %result
+}
+
+define i64 @zext_then_sext(ptr %p, ptr %table, i1 %cold) {
+;
+; CHECK-LABEL: @zext_then_sext(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[V:%.*]] = load i8, ptr [[P:%.*]], align 1
+; CHECK-NEXT:    [[V32:%.*]] = zext i8 [[V]] to i32
+; CHECK-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
+; CHECK:       call:
+; CHECK-NEXT:    call void @consume(i32 [[V32]])
+; CHECK-NEXT:    br label [[JOIN]]
+; CHECK:       join:
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i32 [[V32]] to i8
+; CHECK-NEXT:    [[V64:%.*]] = sext i8 [[TMP0]] to i64
+; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[TABLE:%.*]], i64 [[V64]]
+; CHECK-NEXT:    [[MASK:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    [[SUM:%.*]] = add i32 [[MASK]], [[V32]]
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i32 [[SUM]] to i64
+; CHECK-NEXT:    ret i64 [[RESULT]]
+;
+entry:
+  %v = load i8, ptr %p
+  %v32 = zext i8 %v to i32
+  br i1 %cold, label %call, label %join
+call:
+  call void @consume(i32 %v32)
+  br label %join
+join:
+  %v64 = sext i8 %v to i64
+  %ptr = getelementptr i32, ptr %table, i64 %v64
+  %mask = load i32, ptr %ptr
+  %sum = add i32 %mask, %v32
+  %result = zext i32 %sum to i64
+  ret i64 %result
+}
+
+
+define i64 @sext_address(ptr %p, ptr %table, i1 %cold) {
+; AARCH64-LABEL: @sext_address(
+; AARCH64-NEXT:  entry:
+; AARCH64-NEXT:    [[V:%.*]] = load i8, ptr [[P:%.*]], align 1
+; AARCH64-NEXT:    [[V64:%.*]] = sext i8 [[V]] to i64
+; AARCH64-NEXT:    [[V32:%.*]] = sext i8 [[V]] to i32
+; AARCH64-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
+; AARCH64:       call:
+; AARCH64-NEXT:    call void @consume(i32 [[V32]])
+; AARCH64-NEXT:    br label [[JOIN]]
+; AARCH64:       join:
+; AARCH64-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[TABLE:%.*]], i64 [[V64]]
+; AARCH64-NEXT:    [[MASK:%.*]] = load i32, ptr [[PTR]], align 4
+; AARCH64-NEXT:    [[SUM:%.*]] = add i32 [[MASK]], [[V32]]
+; AARCH64-NEXT:    [[RESULT:%.*]] = zext i32 [[SUM]] to i64
+; AARCH64-NEXT:    ret i64 [[RESULT]]
+;
+; X86-LABEL: @sext_address(
+; X86-NEXT:  entry:
+; X86-NEXT:    [[V:%.*]] = load i8, ptr [[P:%.*]], align 1
+; X86-NEXT:    [[V32:%.*]] = sext i8 [[V]] to i32
+; X86-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
+; X86:       call:
+; X86-NEXT:    call void @consume(i32 [[V32]])
+; X86-NEXT:    br label [[JOIN]]
+; X86:       join:
+; X86-NEXT:    [[TMP0:%.*]] = trunc i32 [[V32]] to i8
+; X86-NEXT:    [[V64:%.*]] = sext i8 [[TMP0]] to i64
+; X86-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[TABLE:%.*]], i64 [[V64]]
+; X86-NEXT:    [[MASK:%.*]] = load i32, ptr [[PTR]], align 4
+; X86-NEXT:    [[SUM:%.*]] = add i32 [[MASK]], [[V32]]
+; X86-NEXT:    [[RESULT:%.*]] = zext i32 [[SUM]] to i64
+; X86-NEXT:    ret i64 [[RESULT]]
+;
+entry:
+  %v = load i8, ptr %p
+  %v32 = sext i8 %v to i32
+  br i1 %cold, label %call, label %join
+call:
+  call void @consume(i32 %v32)
+  br label %join
+join:
+  %v64 = sext i8 %v to i64
+  %ptr = getelementptr i32, ptr %table, i64 %v64
+  %mask = load i32, ptr %ptr
+  %sum = add i32 %mask, %v32
+  %result = zext i32 %sum to i64
+  ret i64 %result
+}
+
+define i64 @sext_standalone(ptr %p, ptr %table, i1 %cold) {
+; CHECK-LABEL: @sext_standalone(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[V:%.*]] = load i8, ptr [[P:%.*]], align 1
+; CHECK-NEXT:    [[V32:%.*]] = sext i8 [[V]] to i32
+; CHECK-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
+; CHECK:       call:
+; CHECK-NEXT:    call void @consume(i32 [[V32]])
+; CHECK-NEXT:    br label [[JOIN]]
+; CHECK:       join:
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i32 [[V32]] to i8
+; CHECK-NEXT:    [[V64:%.*]] = sext i8 [[TMP0]] to i64
+; CHECK-NEXT:    call void @consume64(i64 [[V64]])
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i32 [[V32]] to i64
+; CHECK-NEXT:    ret i64 [[RESULT]]
+;
+entry:
+  %v = load i8, ptr %p
+  %v32 = sext i8 %v to i32
+  br i1 %cold, label %call, label %join
+call:
+  call void @consume(i32 %v32)
+  br label %join
+join:
+  %v64 = sext i8 %v to i64
+  call void @consume64(i64 %v64)
+  %result = zext i32 %v32 to i64
+  ret i64 %result
+}

>From 2df6bdb373b2b96d304e055a0af3726f6259e993 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1vid=20Bolvansk=C3=BD?= <david.bolvansky at gmail.com>
Date: Sat, 3 Oct 2026 19:54:07 +0200
Subject: [PATCH 2/2] Query zero-extension cost before changing operands and
 check final x86 assembly

---
 llvm/lib/CodeGen/CodeGenPrepare.cpp           | 17 ++--
 llvm/test/CodeGen/X86/reuse-extension.ll      | 95 +++++++++++++++++++
 .../CodeGenPrepare/reuse-extension.ll         | 53 ++++-------
 3 files changed, 122 insertions(+), 43 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/reuse-extension.ll

diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index fbb4d3b4e0261..48a57f8017a5c 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -7391,20 +7391,17 @@ bool CodeGenPrepare::optimizeExtUses(Instruction *I) {
       continue;
 
     // Both src and def are live in this block. Rewrite the use.
-    // Reuse an extension directly when a wider extension of the same kind is
-    // free for its users.
+    // Reuse a zero extension directly when a wider zero extension is free.
     // Going through a truncation instead can hide an extending-load
     // opportunity.
-    if (I->getOpcode() == User->getOpcode() &&
+    if (isa<ZExtInst>(I) && isa<ZExtInst>(User) &&
         User->getType()->getScalarSizeInBits() >
-            I->getType()->getScalarSizeInBits()) {
+            I->getType()->getScalarSizeInBits() &&
+        TLI->isZExtFree(I->getType(), User->getType())) {
       U = I;
-      if (TLI->isExtFree(User)) {
-        ++NumExtUses;
-        MadeChange = true;
-        continue;
-      }
-      U = Src;
+      ++NumExtUses;
+      MadeChange = true;
+      continue;
     }
 
     Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
diff --git a/llvm/test/CodeGen/X86/reuse-extension.ll b/llvm/test/CodeGen/X86/reuse-extension.ll
new file mode 100644
index 0000000000000..38fd66ef27f43
--- /dev/null
+++ b/llvm/test/CodeGen/X86/reuse-extension.ll
@@ -0,0 +1,95 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64 -verify-machineinstrs < %s | FileCheck %s
+
+; Reusing the extending load's register avoids a redundant 32-bit copy before
+; the indexed memory operand, even when the value survives a call.
+declare void @consume(i32)
+
+define i64 @zext_i8(ptr %p, ptr %table, i1 %cold) {
+; CHECK-LABEL: zext_i8:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    .cfi_offset %rbx, -24
+; CHECK-NEXT:    .cfi_offset %r14, -16
+; CHECK-NEXT:    movq %rsi, %rbx
+; CHECK-NEXT:    movzbl (%rdi), %r14d
+; CHECK-NEXT:    testb $1, %dl
+; CHECK-NEXT:    je .LBB0_2
+; CHECK-NEXT:  # %bb.1: # %call
+; CHECK-NEXT:    movl %r14d, %edi
+; CHECK-NEXT:    callq consume at PLT
+; CHECK-NEXT:  .LBB0_2: # %join
+; CHECK-NEXT:    addl (%rbx,%r14,4), %r14d
+; CHECK-NEXT:    movq %r14, %rax
+; CHECK-NEXT:    addq $8, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+entry:
+  %v = load i8, ptr %p
+  %v32 = zext i8 %v to i32
+  br i1 %cold, label %call, label %join
+call:
+  call void @consume(i32 %v32)
+  br label %join
+join:
+  %v64 = zext i8 %v to i64
+  %ptr = getelementptr i32, ptr %table, i64 %v64
+  %mask = load i32, ptr %ptr
+  %sum = add i32 %mask, %v32
+  %result = zext i32 %sum to i64
+  ret i64 %result
+}
+
+define i64 @zext_i16(ptr %p, ptr %table, i1 %cold) {
+; CHECK-LABEL: zext_i16:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    .cfi_offset %rbx, -24
+; CHECK-NEXT:    .cfi_offset %r14, -16
+; CHECK-NEXT:    movq %rsi, %rbx
+; CHECK-NEXT:    movzwl (%rdi), %r14d
+; CHECK-NEXT:    testb $1, %dl
+; CHECK-NEXT:    je .LBB1_2
+; CHECK-NEXT:  # %bb.1: # %call
+; CHECK-NEXT:    movl %r14d, %edi
+; CHECK-NEXT:    callq consume at PLT
+; CHECK-NEXT:  .LBB1_2: # %join
+; CHECK-NEXT:    addl (%rbx,%r14,4), %r14d
+; CHECK-NEXT:    movq %r14, %rax
+; CHECK-NEXT:    addq $8, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+entry:
+  %v = load i16, ptr %p
+  %v32 = zext i16 %v to i32
+  br i1 %cold, label %call, label %join
+call:
+  call void @consume(i32 %v32)
+  br label %join
+join:
+  %v64 = zext i16 %v to i64
+  %ptr = getelementptr i32, ptr %table, i64 %v64
+  %mask = load i32, ptr %ptr
+  %sum = add i32 %mask, %v32
+  %result = zext i32 %sum to i64
+  ret i64 %result
+}
+
diff --git a/llvm/test/Transforms/CodeGenPrepare/reuse-extension.ll b/llvm/test/Transforms/CodeGenPrepare/reuse-extension.ll
index 8484ea8b42f7a..6762cfb44641c 100644
--- a/llvm/test/Transforms/CodeGenPrepare/reuse-extension.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/reuse-extension.ll
@@ -3,7 +3,7 @@
 ; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -mtriple=x86_64 < %s | FileCheck %s --check-prefixes=CHECK,X86
 ; REQUIRES: aarch64-registered-target, x86-registered-target
 
-; Reusing a free wider extension must not introduce a truncation that
+; Reusing a free wider zero extension must not introduce a truncation that
 ; prevents CodeGenPrepare from moving the extension to the original load.
 declare void @consume(i32)
 declare void @consume64(i64)
@@ -148,38 +148,22 @@ join:
 
 
 define i64 @sext_address(ptr %p, ptr %table, i1 %cold) {
-; AARCH64-LABEL: @sext_address(
-; AARCH64-NEXT:  entry:
-; AARCH64-NEXT:    [[V:%.*]] = load i8, ptr [[P:%.*]], align 1
-; AARCH64-NEXT:    [[V64:%.*]] = sext i8 [[V]] to i64
-; AARCH64-NEXT:    [[V32:%.*]] = sext i8 [[V]] to i32
-; AARCH64-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
-; AARCH64:       call:
-; AARCH64-NEXT:    call void @consume(i32 [[V32]])
-; AARCH64-NEXT:    br label [[JOIN]]
-; AARCH64:       join:
-; AARCH64-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[TABLE:%.*]], i64 [[V64]]
-; AARCH64-NEXT:    [[MASK:%.*]] = load i32, ptr [[PTR]], align 4
-; AARCH64-NEXT:    [[SUM:%.*]] = add i32 [[MASK]], [[V32]]
-; AARCH64-NEXT:    [[RESULT:%.*]] = zext i32 [[SUM]] to i64
-; AARCH64-NEXT:    ret i64 [[RESULT]]
-;
-; X86-LABEL: @sext_address(
-; X86-NEXT:  entry:
-; X86-NEXT:    [[V:%.*]] = load i8, ptr [[P:%.*]], align 1
-; X86-NEXT:    [[V32:%.*]] = sext i8 [[V]] to i32
-; X86-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
-; X86:       call:
-; X86-NEXT:    call void @consume(i32 [[V32]])
-; X86-NEXT:    br label [[JOIN]]
-; X86:       join:
-; X86-NEXT:    [[TMP0:%.*]] = trunc i32 [[V32]] to i8
-; X86-NEXT:    [[V64:%.*]] = sext i8 [[TMP0]] to i64
-; X86-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[TABLE:%.*]], i64 [[V64]]
-; X86-NEXT:    [[MASK:%.*]] = load i32, ptr [[PTR]], align 4
-; X86-NEXT:    [[SUM:%.*]] = add i32 [[MASK]], [[V32]]
-; X86-NEXT:    [[RESULT:%.*]] = zext i32 [[SUM]] to i64
-; X86-NEXT:    ret i64 [[RESULT]]
+; CHECK-LABEL: @sext_address(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[V:%.*]] = load i8, ptr [[P:%.*]], align 1
+; CHECK-NEXT:    [[V32:%.*]] = sext i8 [[V]] to i32
+; CHECK-NEXT:    br i1 [[COLD:%.*]], label [[CALL:%.*]], label [[JOIN:%.*]]
+; CHECK:       call:
+; CHECK-NEXT:    call void @consume(i32 [[V32]])
+; CHECK-NEXT:    br label [[JOIN]]
+; CHECK:       join:
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i32 [[V32]] to i8
+; CHECK-NEXT:    [[V64:%.*]] = sext i8 [[TMP0]] to i64
+; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[TABLE:%.*]], i64 [[V64]]
+; CHECK-NEXT:    [[MASK:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    [[SUM:%.*]] = add i32 [[MASK]], [[V32]]
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i32 [[SUM]] to i64
+; CHECK-NEXT:    ret i64 [[RESULT]]
 ;
 entry:
   %v = load i8, ptr %p
@@ -226,3 +210,6 @@ join:
   %result = zext i32 %v32 to i64
   ret i64 %result
 }
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; AARCH64: {{.*}}
+; X86: {{.*}}



More information about the llvm-commits mailing list