[llvm] [AArch64][FastISel] Add sext/zext tests demonstrating a few existing bugs (NFC) (PR #213654)

Ömer Sinan Ağacan via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 3 05:13:26 PDT 2026


https://github.com/osa1 created https://github.com/llvm/llvm-project/pull/213654

None

>From 79be30b8523688c7f6bd8173afb49f1df2179c7a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= <omer at osa1.net>
Date: Mon, 3 Aug 2026 13:11:34 +0100
Subject: [PATCH] [AArch64][FastISel] Add sext/zext tests demonstrating a few
 existing bugs (NFC)

---
 .../AArch64/arm64-fast-isel-conversion.ll     |  68 ---
 .../AArch64/fast-isel-ext-args-folded.ll      | 400 +++++++++++++++++
 .../CodeGen/AArch64/fast-isel-signext-args.ll | 409 ++++++++++++++++++
 .../CodeGen/AArch64/fast-isel-zeroext-args.ll | 407 +++++++++++++++++
 4 files changed, 1216 insertions(+), 68 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/fast-isel-ext-args-folded.ll
 create mode 100644 llvm/test/CodeGen/AArch64/fast-isel-signext-args.ll
 create mode 100644 llvm/test/CodeGen/AArch64/fast-isel-zeroext-args.ll

diff --git a/llvm/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll b/llvm/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll
index f6ce47a6f988d..fb8a5be3904f3 100644
--- a/llvm/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll
@@ -83,25 +83,6 @@ entry:
   ret i64 %tmp5
 }
 
-define i32 @zext_i1_i32(i1 zeroext %a) nounwind ssp {
-; CHECK-LABEL: zext_i1_i32:
-; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    ret
-entry:
-  %conv = zext i1 %a to i32
-  ret i32 %conv;
-}
-
-define i64 @zext_i1_i64(i1 zeroext %a) nounwind ssp {
-; CHECK-LABEL: zext_i1_i64:
-; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    ; kill: def $x0 killed $w0
-; CHECK-NEXT:    ret
-entry:
-  %conv = zext i1 %a to i64
-  ret i64 %conv;
-}
-
 define i64 @sext_(i8 signext %a, i16 signext %b, i32 %c, i64 %d) nounwind ssp {
 ; CHECK-LABEL: sext_:
 ; CHECK:       ; %bb.0: ; %entry
@@ -141,38 +122,6 @@ entry:
   ret i64 %tmp5
 }
 
-; Test sext i8 to i64
-
-define zeroext i64 @sext_i8_i64(i8 zeroext %in) {
-; CHECK-LABEL: sext_i8_i64:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    mov x8, x0
-; CHECK-NEXT:    sxtb x0, w8
-; CHECK-NEXT:    ret
-  %big = sext i8 %in to i64
-  ret i64 %big
-}
-
-define zeroext i64 @sext_i16_i64(i16 zeroext %in) {
-; CHECK-LABEL: sext_i16_i64:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    mov x8, x0
-; CHECK-NEXT:    sxth x0, w8
-; CHECK-NEXT:    ret
-  %big = sext i16 %in to i64
-  ret i64 %big
-}
-
-; Test sext i1 to i32
-define i32 @sext_i1_i32(i1 signext %a) nounwind ssp {
-; CHECK-LABEL: sext_i1_i32:
-; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    ret
-entry:
-  %conv = sext i1 %a to i32
-  ret i32 %conv
-}
-
 ; Test sext i1 to i16
 define signext i16 @sext_i1_i16(i1 %a) nounwind ssp {
 ; CHECK-LABEL: sext_i1_i16:
@@ -488,23 +437,6 @@ define void @stack_trunc() nounwind {
   ret void
 }
 
-define zeroext i64 @zext_i8_i64(i8 zeroext %in) {
-; CHECK-LABEL: zext_i8_i64:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    ; kill: def $x0 killed $w0
-; CHECK-NEXT:    ret
-  %big = zext i8 %in to i64
-  ret i64 %big
-}
-define zeroext i64 @zext_i16_i64(i16 zeroext %in) {
-; CHECK-LABEL: zext_i16_i64:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    ; kill: def $x0 killed $w0
-; CHECK-NEXT:    ret
-  %big = zext i16 %in to i64
-  ret i64 %big
-}
-
 define float @bitcast_i32_to_float(i32 %a) {
 ; CHECK-LABEL: bitcast_i32_to_float:
 ; CHECK:       ; %bb.0:
diff --git a/llvm/test/CodeGen/AArch64/fast-isel-ext-args-folded.ll b/llvm/test/CodeGen/AArch64/fast-isel-ext-args-folded.ll
new file mode 100644
index 0000000000000..355f404fb79f8
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/fast-isel-ext-args-folded.ll
@@ -0,0 +1,400 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64-apple-darwin -O0 -fast-isel -verify-machineinstrs < %s | FileCheck %s
+
+; shl of a zext of a zerext argument
+
+define i64 @zeroext_zext_i1_shl(i1 zeroext %a) {
+; CHECK-LABEL: zeroext_zext_i1_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+define i64 @zeroext_zext_i8_shl(i8 zeroext %a) {
+; CHECK-LABEL: zeroext_zext_i8_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+define i64 @zeroext_zext_i16_shl(i16 zeroext %a) {
+; CHECK-LABEL: zeroext_zext_i16_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+define i64 @zeroext_zext_i32_shl(i32 zeroext %a) {
+; CHECK-LABEL: zeroext_zext_i32_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+; shl of a sext of a signext argument
+
+; FIXME
+define i64 @signext_sext_i1_shl(i1 signext %a) {
+; CHECK-LABEL: signext_sext_i1_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+; FIXME
+define i64 @signext_sext_i8_shl(i8 signext %a) {
+; CHECK-LABEL: signext_sext_i8_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+; FIXME
+define i64 @signext_sext_i16_shl(i16 signext %a) {
+; CHECK-LABEL: signext_sext_i16_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+; FIXME
+define i64 @signext_sext_i32_shl(i32 signext %a) {
+; CHECK-LABEL: signext_sext_i32_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+; shl of a sext of a zeroext argument
+
+define i64 @zeroext_sext_i1_shl(i1 zeroext %a) {
+; CHECK-LABEL: zeroext_sext_i1_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sbfiz x0, x8, #3, #1
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+define i64 @zeroext_sext_i8_shl(i8 zeroext %a) {
+; CHECK-LABEL: zeroext_sext_i8_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sbfiz x0, x8, #3, #8
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+define i64 @zeroext_sext_i16_shl(i16 zeroext %a) {
+; CHECK-LABEL: zeroext_sext_i16_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sbfiz x0, x8, #3, #16
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+define i64 @zeroext_sext_i32_shl(i32 zeroext %a) {
+; CHECK-LABEL: zeroext_sext_i32_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sbfiz x0, x8, #3, #32
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+; shl of a zext of a signext argument
+
+define i64 @signext_zext_i1_shl(i1 signext %a) {
+; CHECK-LABEL: signext_zext_i1_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfiz x0, x8, #3, #1
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+define i64 @signext_zext_i8_shl(i8 signext %a) {
+; CHECK-LABEL: signext_zext_i8_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfiz x0, x8, #3, #8
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+define i64 @signext_zext_i16_shl(i16 signext %a) {
+; CHECK-LABEL: signext_zext_i16_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfiz x0, x8, #3, #16
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+define i64 @signext_zext_i32_shl(i32 signext %a) {
+; CHECK-LABEL: signext_zext_i32_shl:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfiz x0, x8, #3, #32
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  %r = shl i64 %e, 3
+  ret i64 %r
+}
+
+; mul of a zext of a zeroext argument
+
+define i64 @zeroext_zext_i1_mul(i1 zeroext %a) {
+; CHECK-LABEL: zeroext_zext_i1_mul:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i64
+  %r = mul i64 %e, 8
+  ret i64 %r
+}
+
+define i64 @zeroext_zext_i8_mul(i8 zeroext %a) {
+; CHECK-LABEL: zeroext_zext_i8_mul:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i64
+  %r = mul i64 %e, 8
+  ret i64 %r
+}
+
+define i64 @zeroext_zext_i16_mul(i16 zeroext %a) {
+; CHECK-LABEL: zeroext_zext_i16_mul:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i64
+  %r = mul i64 %e, 8
+  ret i64 %r
+}
+
+define i64 @zeroext_zext_i32_mul(i32 zeroext %a) {
+; CHECK-LABEL: zeroext_zext_i32_mul:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  %r = mul i64 %e, 8
+  ret i64 %r
+}
+
+; mul of a sext of a signext argument
+
+; FIXME
+define i64 @signext_sext_i1_mul(i1 signext %a) {
+; CHECK-LABEL: signext_sext_i1_mul:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i64
+  %r = mul i64 %e, 8
+  ret i64 %r
+}
+
+; FIXME
+define i64 @signext_sext_i8_mul(i8 signext %a) {
+; CHECK-LABEL: signext_sext_i8_mul:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i64
+  %r = mul i64 %e, 8
+  ret i64 %r
+}
+
+; FIXME
+define i64 @signext_sext_i16_mul(i16 signext %a) {
+; CHECK-LABEL: signext_sext_i16_mul:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i64
+  %r = mul i64 %e, 8
+  ret i64 %r
+}
+
+; FIXME
+define i64 @signext_sext_i32_mul(i32 signext %a) {
+; CHECK-LABEL: signext_sext_i32_mul:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    lsl x0, x8, #3
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  %r = mul i64 %e, 8
+  ret i64 %r
+}
+
+; extension used as a gep index (address-mode folding)
+
+define i64 @zeroext_zext_i32_gep(i32 zeroext %a, ptr %p) {
+; CHECK-LABEL: zeroext_zext_i32_gep:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    mov x9, #8 ; =0x8
+; CHECK-NEXT:    mul x8, x8, x9
+; CHECK-NEXT:    add x8, x1, x8
+; CHECK-NEXT:    ldr x0, [x8]
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  %g = getelementptr i64, ptr %p, i64 %e
+  %v = load i64, ptr %g
+  ret i64 %v
+}
+
+; FIXME
+define i64 @signext_sext_i32_gep(i32 signext %a, ptr %p) {
+; CHECK-LABEL: signext_sext_i32_gep:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    mov x9, #8 ; =0x8
+; CHECK-NEXT:    mul x8, x8, x9
+; CHECK-NEXT:    add x8, x1, x8
+; CHECK-NEXT:    ldr x0, [x8]
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  %g = getelementptr i64, ptr %p, i64 %e
+  %v = load i64, ptr %g
+  ret i64 %v
+}
+
+define i64 @zeroext_sext_i32_gep(i32 zeroext %a, ptr %p) {
+; CHECK-LABEL: zeroext_sext_i32_gep:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sxtw x8, w8
+; CHECK-NEXT:    mov x9, #8 ; =0x8
+; CHECK-NEXT:    mul x8, x8, x9
+; CHECK-NEXT:    add x8, x1, x8
+; CHECK-NEXT:    ldr x0, [x8]
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  %g = getelementptr i64, ptr %p, i64 %e
+  %v = load i64, ptr %g
+  ret i64 %v
+}
+
+define i64 @signext_zext_i32_gep(i32 signext %a, ptr %p) {
+; CHECK-LABEL: signext_zext_i32_gep:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfx x8, x8, #0, #32
+; CHECK-NEXT:    mov x9, #8 ; =0x8
+; CHECK-NEXT:    mul x8, x8, x9
+; CHECK-NEXT:    add x8, x1, x8
+; CHECK-NEXT:    ldr x0, [x8]
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  %g = getelementptr i64, ptr %p, i64 %e
+  %v = load i64, ptr %g
+  ret i64 %v
+}
+
+; extension used as an add operand
+
+define i64 @zeroext_zext_i32_add(i32 zeroext %a, i64 %b) {
+; CHECK-LABEL: zeroext_zext_i32_add:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    add x0, x1, x8
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  %r = add i64 %b, %e
+  ret i64 %r
+}
+
+; FIXME
+define i64 @signext_sext_i32_add(i32 signext %a, i64 %b) {
+; CHECK-LABEL: signext_sext_i32_add:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    add x0, x1, x8
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  %r = add i64 %b, %e
+  ret i64 %r
+}
+
+define i64 @zeroext_sext_i32_add(i32 zeroext %a, i64 %b) {
+; CHECK-LABEL: zeroext_sext_i32_add:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sxtw x8, w8
+; CHECK-NEXT:    add x0, x1, x8
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  %r = add i64 %b, %e
+  ret i64 %r
+}
+
+define i64 @signext_zext_i32_add(i32 signext %a, i64 %b) {
+; CHECK-LABEL: signext_zext_i32_add:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfx x8, x8, #0, #32
+; CHECK-NEXT:    add x0, x1, x8
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  %r = add i64 %b, %e
+  ret i64 %r
+}
diff --git a/llvm/test/CodeGen/AArch64/fast-isel-signext-args.ll b/llvm/test/CodeGen/AArch64/fast-isel-signext-args.ll
new file mode 100644
index 0000000000000..6281bf4eb7b06
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/fast-isel-signext-args.ll
@@ -0,0 +1,409 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64-apple-darwin -O0 -fast-isel -verify-machineinstrs < %s | FileCheck %s
+
+define i8 @zext_i1_to_i8(i1 signext %a) {
+; CHECK-LABEL: zext_i1_to_i8:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w0, w0, #0x1
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i8
+  ret i8 %e
+}
+
+define void @zext_i1_to_i8_store(i1 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i1_to_i8_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w8, w0, #0x1
+; CHECK-NEXT:    strb w8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i8
+  store i8 %e, ptr %p
+  ret void
+}
+
+define i8 @sext_i1_to_i8(i1 signext %a) {
+; CHECK-LABEL: sext_i1_to_i8:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sbfx w0, w0, #0, #1
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i8
+  ret i8 %e
+}
+
+define void @sext_i1_to_i8_store(i1 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i1_to_i8_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    strb w0, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i8
+  store i8 %e, ptr %p
+  ret void
+}
+
+define i16 @zext_i1_to_i16(i1 signext %a) {
+; CHECK-LABEL: zext_i1_to_i16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w0, w0, #0x1
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i16
+  ret i16 %e
+}
+
+define void @zext_i1_to_i16_store(i1 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i1_to_i16_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w8, w0, #0x1
+; CHECK-NEXT:    strh w8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i16
+  store i16 %e, ptr %p
+  ret void
+}
+
+define i16 @sext_i1_to_i16(i1 signext %a) {
+; CHECK-LABEL: sext_i1_to_i16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sbfx w0, w0, #0, #1
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i16
+  ret i16 %e
+}
+
+define void @sext_i1_to_i16_store(i1 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i1_to_i16_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    strh w0, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i16
+  store i16 %e, ptr %p
+  ret void
+}
+
+define i32 @zext_i1_to_i32(i1 signext %a) {
+; CHECK-LABEL: zext_i1_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w0, w0, #0x1
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i32
+  ret i32 %e
+}
+
+define void @zext_i1_to_i32_store(i1 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i1_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w8, w0, #0x1
+; CHECK-NEXT:    str w8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+define i32 @sext_i1_to_i32(i1 signext %a) {
+; CHECK-LABEL: sext_i1_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i32
+  ret i32 %e
+}
+
+define void @sext_i1_to_i32_store(i1 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i1_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    str w0, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+define i64 @zext_i1_to_i64(i1 signext %a) {
+; CHECK-LABEL: zext_i1_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w8, w0, #0x1
+; CHECK-NEXT:    mov w0, w8
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i64
+  ret i64 %e
+}
+
+define void @zext_i1_to_i64_store(i1 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i1_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w8, w0, #0x1
+; CHECK-NEXT:    ; kill: def $x8 killed $w8
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+; FIXME
+define i64 @sext_i1_to_i64(i1 signext %a) {
+; CHECK-LABEL: sext_i1_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; kill: def $x0 killed $w0
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i64
+  ret i64 %e
+}
+
+; FIXME
+define void @sext_i1_to_i64_store(i1 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i1_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+define i16 @zext_i8_to_i16(i8 signext %a) {
+; CHECK-LABEL: zext_i8_to_i16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w0, w0, #0xff
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i16
+  ret i16 %e
+}
+
+define void @zext_i8_to_i16_store(i8 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i8_to_i16_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    uxtb w8, w0
+; CHECK-NEXT:    strh w8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i16
+  store i16 %e, ptr %p
+  ret void
+}
+
+define i16 @sext_i8_to_i16(i8 signext %a) {
+; CHECK-LABEL: sext_i8_to_i16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sxtb w0, w0
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i16
+  ret i16 %e
+}
+
+define void @sext_i8_to_i16_store(i8 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i8_to_i16_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    strh w0, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i16
+  store i16 %e, ptr %p
+  ret void
+}
+
+define i32 @zext_i8_to_i32(i8 signext %a) {
+; CHECK-LABEL: zext_i8_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    uxtb w0, w0
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i32
+  ret i32 %e
+}
+
+define void @zext_i8_to_i32_store(i8 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i8_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    uxtb w8, w0
+; CHECK-NEXT:    str w8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+define i32 @sext_i8_to_i32(i8 signext %a) {
+; CHECK-LABEL: sext_i8_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i32
+  ret i32 %e
+}
+
+define void @sext_i8_to_i32_store(i8 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i8_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    str w0, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+define i64 @zext_i8_to_i64(i8 signext %a) {
+; CHECK-LABEL: zext_i8_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfx x0, x8, #0, #8
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i64
+  ret i64 %e
+}
+
+define void @zext_i8_to_i64_store(i8 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i8_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfx x8, x8, #0, #8
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+; FIXME
+define i64 @sext_i8_to_i64(i8 signext %a) {
+; CHECK-LABEL: sext_i8_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; kill: def $x0 killed $w0
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i64
+  ret i64 %e
+}
+
+; FIXME
+define void @sext_i8_to_i64_store(i8 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i8_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+define i32 @zext_i16_to_i32(i16 signext %a) {
+; CHECK-LABEL: zext_i16_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    uxth w0, w0
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i32
+  ret i32 %e
+}
+
+define void @zext_i16_to_i32_store(i16 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i16_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    uxth w8, w0
+; CHECK-NEXT:    str w8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+define i32 @sext_i16_to_i32(i16 signext %a) {
+; CHECK-LABEL: sext_i16_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i32
+  ret i32 %e
+}
+
+define void @sext_i16_to_i32_store(i16 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i16_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    str w0, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+define i64 @zext_i16_to_i64(i16 signext %a) {
+; CHECK-LABEL: zext_i16_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfx x0, x8, #0, #16
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i64
+  ret i64 %e
+}
+
+define void @zext_i16_to_i64_store(i16 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i16_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfx x8, x8, #0, #16
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+; FIXME
+define i64 @sext_i16_to_i64(i16 signext %a) {
+; CHECK-LABEL: sext_i16_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; kill: def $x0 killed $w0
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i64
+  ret i64 %e
+}
+
+; FIXME
+define void @sext_i16_to_i64_store(i16 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i16_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+define i64 @zext_i32_to_i64(i32 signext %a) {
+; CHECK-LABEL: zext_i32_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfx x0, x8, #0, #32
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  ret i64 %e
+}
+
+define void @zext_i32_to_i64_store(i32 signext %a, ptr %p) {
+; CHECK-LABEL: zext_i32_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    ubfx x8, x8, #0, #32
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+; FIXME
+define i64 @sext_i32_to_i64(i32 signext %a) {
+; CHECK-LABEL: sext_i32_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; kill: def $x0 killed $w0
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  ret i64 %e
+}
+
+; FIXME
+define void @sext_i32_to_i64_store(i32 signext %a, ptr %p) {
+; CHECK-LABEL: sext_i32_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
diff --git a/llvm/test/CodeGen/AArch64/fast-isel-zeroext-args.ll b/llvm/test/CodeGen/AArch64/fast-isel-zeroext-args.ll
new file mode 100644
index 0000000000000..dda93ee71c3a6
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/fast-isel-zeroext-args.ll
@@ -0,0 +1,407 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64-apple-darwin -O0 -fast-isel -verify-machineinstrs < %s | FileCheck %s
+
+define i8 @zext_i1_to_i8(i1 zeroext %a) {
+; CHECK-LABEL: zext_i1_to_i8:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w0, w0, #0x1
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i8
+  ret i8 %e
+}
+
+define void @zext_i1_to_i8_store(i1 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i1_to_i8_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    strb w0, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i8
+  store i8 %e, ptr %p
+  ret void
+}
+
+define i8 @sext_i1_to_i8(i1 zeroext %a) {
+; CHECK-LABEL: sext_i1_to_i8:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sbfx w0, w0, #0, #1
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i8
+  ret i8 %e
+}
+
+define void @sext_i1_to_i8_store(i1 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i1_to_i8_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sbfx w8, w0, #0, #1
+; CHECK-NEXT:    strb w8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i8
+  store i8 %e, ptr %p
+  ret void
+}
+
+define i16 @zext_i1_to_i16(i1 zeroext %a) {
+; CHECK-LABEL: zext_i1_to_i16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w0, w0, #0x1
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i16
+  ret i16 %e
+}
+
+define void @zext_i1_to_i16_store(i1 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i1_to_i16_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    strh w0, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i16
+  store i16 %e, ptr %p
+  ret void
+}
+
+define i16 @sext_i1_to_i16(i1 zeroext %a) {
+; CHECK-LABEL: sext_i1_to_i16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sbfx w0, w0, #0, #1
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i16
+  ret i16 %e
+}
+
+define void @sext_i1_to_i16_store(i1 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i1_to_i16_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sbfx w8, w0, #0, #1
+; CHECK-NEXT:    strh w8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i16
+  store i16 %e, ptr %p
+  ret void
+}
+
+define i32 @zext_i1_to_i32(i1 zeroext %a) {
+; CHECK-LABEL: zext_i1_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i32
+  ret i32 %e
+}
+
+define void @zext_i1_to_i32_store(i1 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i1_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    str w0, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+define i32 @sext_i1_to_i32(i1 zeroext %a) {
+; CHECK-LABEL: sext_i1_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sbfx w0, w0, #0, #1
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i32
+  ret i32 %e
+}
+
+define void @sext_i1_to_i32_store(i1 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i1_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sbfx w8, w0, #0, #1
+; CHECK-NEXT:    str w8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+; FIXME: no extension emitted, bits 63:32 are the caller's.
+define i64 @zext_i1_to_i64(i1 zeroext %a) {
+; CHECK-LABEL: zext_i1_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; kill: def $x0 killed $w0
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i64
+  ret i64 %e
+}
+
+define void @zext_i1_to_i64_store(i1 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i1_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i1 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+define i64 @sext_i1_to_i64(i1 zeroext %a) {
+; CHECK-LABEL: sext_i1_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; implicit-def: $x8
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sbfx x0, x8, #0, #1
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i64
+  ret i64 %e
+}
+
+define void @sext_i1_to_i64_store(i1 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i1_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; implicit-def: $x8
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sbfx x8, x8, #0, #1
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i1 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+define i16 @zext_i8_to_i16(i8 zeroext %a) {
+; CHECK-LABEL: zext_i8_to_i16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    and w0, w0, #0xff
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i16
+  ret i16 %e
+}
+
+define void @zext_i8_to_i16_store(i8 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i8_to_i16_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    strh w0, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i16
+  store i16 %e, ptr %p
+  ret void
+}
+
+define i16 @sext_i8_to_i16(i8 zeroext %a) {
+; CHECK-LABEL: sext_i8_to_i16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sxtb w0, w0
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i16
+  ret i16 %e
+}
+
+define void @sext_i8_to_i16_store(i8 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i8_to_i16_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sxtb w8, w0
+; CHECK-NEXT:    strh w8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i16
+  store i16 %e, ptr %p
+  ret void
+}
+
+define i32 @zext_i8_to_i32(i8 zeroext %a) {
+; CHECK-LABEL: zext_i8_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i32
+  ret i32 %e
+}
+
+define void @zext_i8_to_i32_store(i8 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i8_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    str w0, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+define i32 @sext_i8_to_i32(i8 zeroext %a) {
+; CHECK-LABEL: sext_i8_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sxtb w0, w0
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i32
+  ret i32 %e
+}
+
+define void @sext_i8_to_i32_store(i8 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i8_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sxtb w8, w0
+; CHECK-NEXT:    str w8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+; FIXME: no extension emitted, bits 63:32 are the caller's.
+define i64 @zext_i8_to_i64(i8 zeroext %a) {
+; CHECK-LABEL: zext_i8_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; kill: def $x0 killed $w0
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i64
+  ret i64 %e
+}
+
+define void @zext_i8_to_i64_store(i8 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i8_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i8 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+define i64 @sext_i8_to_i64(i8 zeroext %a) {
+; CHECK-LABEL: sext_i8_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sxtb x0, w8
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i64
+  ret i64 %e
+}
+
+define void @sext_i8_to_i64_store(i8 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i8_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sxtb x8, w8
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i8 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+define i32 @zext_i16_to_i32(i16 zeroext %a) {
+; CHECK-LABEL: zext_i16_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i32
+  ret i32 %e
+}
+
+define void @zext_i16_to_i32_store(i16 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i16_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    str w0, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+define i32 @sext_i16_to_i32(i16 zeroext %a) {
+; CHECK-LABEL: sext_i16_to_i32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sxth w0, w0
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i32
+  ret i32 %e
+}
+
+define void @sext_i16_to_i32_store(i16 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i16_to_i32_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    sxth w8, w0
+; CHECK-NEXT:    str w8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i32
+  store i32 %e, ptr %p
+  ret void
+}
+
+; FIXME: no extension emitted, bits 63:32 are the caller's.
+define i64 @zext_i16_to_i64(i16 zeroext %a) {
+; CHECK-LABEL: zext_i16_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; kill: def $x0 killed $w0
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i64
+  ret i64 %e
+}
+
+define void @zext_i16_to_i64_store(i16 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i16_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i16 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+define i64 @sext_i16_to_i64(i16 zeroext %a) {
+; CHECK-LABEL: sext_i16_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sxth x0, w8
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i64
+  ret i64 %e
+}
+
+define void @sext_i16_to_i64_store(i16 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i16_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sxth x8, w8
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i16 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+; FIXME: no extension emitted, bits 63:32 are the caller's.
+define i64 @zext_i32_to_i64(i32 zeroext %a) {
+; CHECK-LABEL: zext_i32_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    ; kill: def $x0 killed $w0
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  ret i64 %e
+}
+
+define void @zext_i32_to_i64_store(i32 zeroext %a, ptr %p) {
+; CHECK-LABEL: zext_i32_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = zext i32 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}
+
+define i64 @sext_i32_to_i64(i32 zeroext %a) {
+; CHECK-LABEL: sext_i32_to_i64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sxtw x0, w8
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  ret i64 %e
+}
+
+define void @sext_i32_to_i64_store(i32 zeroext %a, ptr %p) {
+; CHECK-LABEL: sext_i32_to_i64_store:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    mov w8, w0
+; CHECK-NEXT:    sxtw x8, w8
+; CHECK-NEXT:    str x8, [x1]
+; CHECK-NEXT:    ret
+  %e = sext i32 %a to i64
+  store i64 %e, ptr %p
+  ret void
+}



More information about the llvm-commits mailing list