| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | 
 | ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s | 
 |  | 
 | ; If we have a shift by sign-extended value, we can replace sign-extension | 
 | ; with zero-extension. | 
 |  | 
 | define i32 @t0_shl(i32 %x, i8 %shamt) nounwind { | 
 | ; CHECK-LABEL: t0_shl: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    sxtb w8, w1 | 
 | ; CHECK-NEXT:    lsl w0, w0, w8 | 
 | ; CHECK-NEXT:    ret | 
 |   %shamt_wide = sext i8 %shamt to i32 | 
 |   %r = shl i32 %x, %shamt_wide | 
 |   ret i32 %r | 
 | } | 
 | define i32 @t1_lshr(i32 %x, i8 %shamt) nounwind { | 
 | ; CHECK-LABEL: t1_lshr: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    sxtb w8, w1 | 
 | ; CHECK-NEXT:    lsr w0, w0, w8 | 
 | ; CHECK-NEXT:    ret | 
 |   %shamt_wide = sext i8 %shamt to i32 | 
 |   %r = lshr i32 %x, %shamt_wide | 
 |   ret i32 %r | 
 | } | 
 | define i32 @t2_ashr(i32 %x, i8 %shamt) nounwind { | 
 | ; CHECK-LABEL: t2_ashr: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    sxtb w8, w1 | 
 | ; CHECK-NEXT:    asr w0, w0, w8 | 
 | ; CHECK-NEXT:    ret | 
 |   %shamt_wide = sext i8 %shamt to i32 | 
 |   %r = ashr i32 %x, %shamt_wide | 
 |   ret i32 %r | 
 | } | 
 |  | 
 | define <4 x i32> @t3_vec_shl(<4 x i32> %x, <4 x i8> %shamt) nounwind { | 
 | ; CHECK-LABEL: t3_vec_shl: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    ushll v1.4s, v1.4h, #0 | 
 | ; CHECK-NEXT:    shl v1.4s, v1.4s, #24 | 
 | ; CHECK-NEXT:    sshr v1.4s, v1.4s, #24 | 
 | ; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s | 
 | ; CHECK-NEXT:    ret | 
 |   %shamt_wide = sext <4 x i8> %shamt to <4 x i32> | 
 |   %r = shl <4 x i32> %x, %shamt_wide | 
 |   ret <4 x i32> %r | 
 | } | 
 | define <4 x i32> @t4_vec_lshr(<4 x i32> %x, <4 x i8> %shamt) nounwind { | 
 | ; CHECK-LABEL: t4_vec_lshr: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    ushll v1.4s, v1.4h, #0 | 
 | ; CHECK-NEXT:    shl v1.4s, v1.4s, #24 | 
 | ; CHECK-NEXT:    sshr v1.4s, v1.4s, #24 | 
 | ; CHECK-NEXT:    neg v1.4s, v1.4s | 
 | ; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s | 
 | ; CHECK-NEXT:    ret | 
 |   %shamt_wide = sext <4 x i8> %shamt to <4 x i32> | 
 |   %r = lshr <4 x i32> %x, %shamt_wide | 
 |   ret <4 x i32> %r | 
 | } | 
 | define <4 x i32> @t5_vec_ashr(<4 x i32> %x, <4 x i8> %shamt) nounwind { | 
 | ; CHECK-LABEL: t5_vec_ashr: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    ushll v1.4s, v1.4h, #0 | 
 | ; CHECK-NEXT:    shl v1.4s, v1.4s, #24 | 
 | ; CHECK-NEXT:    sshr v1.4s, v1.4s, #24 | 
 | ; CHECK-NEXT:    neg v1.4s, v1.4s | 
 | ; CHECK-NEXT:    sshl v0.4s, v0.4s, v1.4s | 
 | ; CHECK-NEXT:    ret | 
 |   %shamt_wide = sext <4 x i8> %shamt to <4 x i32> | 
 |   %r = ashr <4 x i32> %x, %shamt_wide | 
 |   ret <4 x i32> %r | 
 | } | 
 |  | 
 | ; This is not valid for funnel shifts | 
 | declare i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %c) | 
 | declare i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %c) | 
 | define i32 @n6_fshl(i32 %x, i32 %y, i8 %shamt) nounwind { | 
 | ; CHECK-LABEL: n6_fshl: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    and w9, w2, #0x1f | 
 | ; CHECK-NEXT:    neg w9, w9 | 
 | ; CHECK-NEXT:    lsl w8, w0, w2 | 
 | ; CHECK-NEXT:    lsr w9, w1, w9 | 
 | ; CHECK-NEXT:    orr w8, w8, w9 | 
 | ; CHECK-NEXT:    tst w2, #0x1f | 
 | ; CHECK-NEXT:    csel w0, w0, w8, eq | 
 | ; CHECK-NEXT:    ret | 
 |   %shamt_wide = sext i8 %shamt to i32 | 
 |   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %shamt_wide) | 
 |   ret i32 %r | 
 | } | 
 | define i32 @n7_fshr(i32 %x, i32 %y, i8 %shamt) nounwind { | 
 | ; CHECK-LABEL: n7_fshr: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    and w9, w2, #0x1f | 
 | ; CHECK-NEXT:    neg w9, w9 | 
 | ; CHECK-NEXT:    lsr w8, w1, w2 | 
 | ; CHECK-NEXT:    lsl w9, w0, w9 | 
 | ; CHECK-NEXT:    orr w8, w9, w8 | 
 | ; CHECK-NEXT:    tst w2, #0x1f | 
 | ; CHECK-NEXT:    csel w0, w1, w8, eq | 
 | ; CHECK-NEXT:    ret | 
 |   %shamt_wide = sext i8 %shamt to i32 | 
 |   %r = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt_wide) | 
 |   ret i32 %r | 
 | } | 
 |  | 
 | define i32 @n8_extrause(i32 %x, i8 %shamt, i32* %shamt_wide_store) nounwind { | 
 | ; CHECK-LABEL: n8_extrause: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    sxtb w8, w1 | 
 | ; CHECK-NEXT:    lsl w0, w0, w8 | 
 | ; CHECK-NEXT:    str w8, [x2] | 
 | ; CHECK-NEXT:    ret | 
 |   %shamt_wide = sext i8 %shamt to i32 | 
 |   store i32 %shamt_wide, i32* %shamt_wide_store, align 4 | 
 |   %r = shl i32 %x, %shamt_wide | 
 |   ret i32 %r | 
 | } |