; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 | FileCheck %s -check-prefixes=CHECK,SSE,SSE2 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s -check-prefixes=CHECK,SSE,SSE42 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s -check-prefixes=CHECK,AVX,AVX2 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=knl | FileCheck %s -check-prefixes=CHECK,AVX,AVX512,AVX512F ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s -check-prefixes=CHECK,AVX,AVX512,AVX512VL ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 -mattr=+avx512vbmi2 | FileCheck %s -check-prefixes=CHECK,AVX,AVX512,AVX512VBMI define i128 @fshl_i128(i128 %a0, i128 %a1, i128 %a2) nounwind { ; CHECK-LABEL: fshl_i128: ; CHECK: # %bb.0: ; CHECK-NEXT: testb $64, %r8b ; CHECK-NEXT: cmovneq %rdi, %rsi ; CHECK-NEXT: cmoveq %rcx, %rdx ; CHECK-NEXT: cmovneq %rcx, %rdi ; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: movl %r8d, %ecx ; CHECK-NEXT: shldq %cl, %rdx, %rax ; CHECK-NEXT: shldq %cl, %rdi, %rsi ; CHECK-NEXT: movq %rsi, %rdx ; CHECK-NEXT: retq %r = call i128 @llvm.fshl.i128(i128 %a0, i128 %a1, i128 %a2) ret i128 %r } define i128 @fshr_i128(i128 %a0, i128 %a1, i128 %a2) nounwind { ; SSE-LABEL: fshr_i128: ; SSE: # %bb.0: ; SSE-NEXT: testb $64, %r8b ; SSE-NEXT: cmoveq %rdi, %rsi ; SSE-NEXT: cmoveq %rcx, %rdi ; SSE-NEXT: movq %rdx, %rax ; SSE-NEXT: cmovneq %rcx, %rax ; SSE-NEXT: movl %r8d, %ecx ; SSE-NEXT: shrdq %cl, %rdi, %rax ; SSE-NEXT: shrdq %cl, %rsi, %rdi ; SSE-NEXT: movq %rdi, %rdx ; SSE-NEXT: retq ; ; AVX-LABEL: fshr_i128: ; AVX: # %bb.0: ; AVX-NEXT: movq %rdx, %rax ; AVX-NEXT: testb $64, %r8b ; AVX-NEXT: cmoveq %rdi, %rsi ; AVX-NEXT: cmoveq %rcx, %rdi ; AVX-NEXT: cmovneq %rcx, %rax ; AVX-NEXT: movl %r8d, %ecx ; AVX-NEXT: shrdq %cl, %rdi, %rax ; AVX-NEXT: shrdq %cl, %rsi, %rdi ; AVX-NEXT: movq %rdi, %rdx ; AVX-NEXT: retq %r = call i128 @llvm.fshr.i128(i128 %a0, i128 %a1, i128 %a2) ret i128 %r } define i128 @fshl_rot_i128(i128 %a0, i128 %a1) nounwind { ; CHECK-LABEL: fshl_rot_i128: ; CHECK: # %bb.0: ; CHECK-NEXT: movq %rdx, %rcx ; CHECK-NEXT: testb $64, %cl ; CHECK-NEXT: movq %rsi, %rdx ; CHECK-NEXT: cmovneq %rdi, %rdx ; CHECK-NEXT: cmovneq %rsi, %rdi ; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: shldq %cl, %rdx, %rax ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx ; CHECK-NEXT: shldq %cl, %rdi, %rdx ; CHECK-NEXT: retq %r = call i128 @llvm.fshl.i128(i128 %a0, i128 %a0, i128 %a1) ret i128 %r } define i128 @fshr_rot_i128(i128 %a0, i128 %a1) nounwind { ; CHECK-LABEL: fshr_rot_i128: ; CHECK: # %bb.0: ; CHECK-NEXT: movq %rdx, %rcx ; CHECK-NEXT: testb $64, %cl ; CHECK-NEXT: movq %rdi, %rdx ; CHECK-NEXT: cmoveq %rsi, %rdx ; CHECK-NEXT: cmoveq %rdi, %rsi ; CHECK-NEXT: movq %rsi, %rax ; CHECK-NEXT: shrdq %cl, %rdx, %rax ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx ; CHECK-NEXT: shrdq %cl, %rsi, %rdx ; CHECK-NEXT: retq %r = call i128 @llvm.fshr.i128(i128 %a0, i128 %a0, i128 %a1) ret i128 %r } define i128 @fshl_i128_load(ptr %p0, ptr %p1, i128 %a2) nounwind { ; SSE-LABEL: fshl_i128_load: ; SSE: # %bb.0: ; SSE-NEXT: movq %rdx, %rcx ; SSE-NEXT: movq (%rdi), %r8 ; SSE-NEXT: testb $64, %cl ; SSE-NEXT: movq 8(%rdi), %rdx ; SSE-NEXT: cmovneq %r8, %rdx ; SSE-NEXT: movq 8(%rsi), %rax ; SSE-NEXT: movq (%rsi), %rsi ; SSE-NEXT: cmoveq %rax, %rsi ; SSE-NEXT: cmovneq %rax, %r8 ; SSE-NEXT: movq %r8, %rax ; SSE-NEXT: shldq %cl, %rsi, %rax ; SSE-NEXT: # kill: def $cl killed $cl killed $rcx ; SSE-NEXT: shldq %cl, %r8, %rdx ; SSE-NEXT: retq ; ; AVX-LABEL: fshl_i128_load: ; AVX: # %bb.0: ; AVX-NEXT: movq %rdx, %rcx ; AVX-NEXT: movq (%rdi), %r8 ; AVX-NEXT: movq 8(%rsi), %rax ; AVX-NEXT: testb $64, %cl ; AVX-NEXT: movq 8(%rdi), %rdx ; AVX-NEXT: cmovneq %r8, %rdx ; AVX-NEXT: movq (%rsi), %rsi ; AVX-NEXT: cmoveq %rax, %rsi ; AVX-NEXT: cmovneq %rax, %r8 ; AVX-NEXT: movq %r8, %rax ; AVX-NEXT: shldq %cl, %rsi, %rax ; AVX-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX-NEXT: shldq %cl, %r8, %rdx ; AVX-NEXT: retq %a0 = load i128, ptr %p0 %a1 = load i128, ptr %p1 %r = call i128 @llvm.fshl.i128(i128 %a0, i128 %a1, i128 %a2) ret i128 %r } define i128 @fshr_i128_load(ptr %p0, ptr %p1, i128 %a2) nounwind { ; CHECK-LABEL: fshr_i128_load: ; CHECK: # %bb.0: ; CHECK-NEXT: movq %rdx, %rcx ; CHECK-NEXT: movq (%rdi), %rdx ; CHECK-NEXT: movq 8(%rsi), %rax ; CHECK-NEXT: testb $64, %cl ; CHECK-NEXT: movq 8(%rdi), %rdi ; CHECK-NEXT: cmoveq %rdx, %rdi ; CHECK-NEXT: cmoveq %rax, %rdx ; CHECK-NEXT: cmoveq (%rsi), %rax ; CHECK-NEXT: shrdq %cl, %rdx, %rax ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx ; CHECK-NEXT: shrdq %cl, %rdi, %rdx ; CHECK-NEXT: retq %a0 = load i128, ptr %p0 %a1 = load i128, ptr %p1 %r = call i128 @llvm.fshr.i128(i128 %a0, i128 %a1, i128 %a2) ret i128 %r } define i128 @fshl_rot_i128_load(ptr %p0, i128 %a2) nounwind { ; CHECK-LABEL: fshl_rot_i128_load: ; CHECK: # %bb.0: ; CHECK-NEXT: movq %rsi, %rcx ; CHECK-NEXT: movq (%rdi), %rsi ; CHECK-NEXT: movq 8(%rdi), %rax ; CHECK-NEXT: testb $64, %cl ; CHECK-NEXT: movq %rax, %rdx ; CHECK-NEXT: cmovneq %rsi, %rdx ; CHECK-NEXT: cmovneq %rax, %rsi ; CHECK-NEXT: movq %rsi, %rax ; CHECK-NEXT: shldq %cl, %rdx, %rax ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx ; CHECK-NEXT: shldq %cl, %rsi, %rdx ; CHECK-NEXT: retq %a0 = load i128, ptr %p0 %r = call i128 @llvm.fshl.i128(i128 %a0, i128 %a0, i128 %a2) ret i128 %r } define i128 @fshr_rot_i128_load(ptr %p0, i128 %a2) nounwind { ; CHECK-LABEL: fshr_rot_i128_load: ; CHECK: # %bb.0: ; CHECK-NEXT: movq %rsi, %rcx ; CHECK-NEXT: movq (%rdi), %rax ; CHECK-NEXT: movq 8(%rdi), %rsi ; CHECK-NEXT: testb $64, %cl ; CHECK-NEXT: movq %rax, %rdx ; CHECK-NEXT: cmoveq %rsi, %rdx ; CHECK-NEXT: cmoveq %rax, %rsi ; CHECK-NEXT: movq %rsi, %rax ; CHECK-NEXT: shrdq %cl, %rdx, %rax ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx ; CHECK-NEXT: shrdq %cl, %rsi, %rdx ; CHECK-NEXT: retq %a0 = load i128, ptr %p0 %r = call i128 @llvm.fshr.i128(i128 %a0, i128 %a0, i128 %a2) ret i128 %r } define i128 @fshl_i128_vector(<2 x i64> %v0, <2 x i64> %v1, i128 %a2) nounwind { ; SSE2-LABEL: fshl_i128_vector: ; SSE2: # %bb.0: ; SSE2-NEXT: movq %rdi, %rcx ; SSE2-NEXT: movq %xmm0, %rsi ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] ; SSE2-NEXT: movq %xmm0, %rdx ; SSE2-NEXT: movq %xmm1, %rdi ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] ; SSE2-NEXT: movq %xmm0, %rax ; SSE2-NEXT: testb $64, %cl ; SSE2-NEXT: cmovneq %rsi, %rdx ; SSE2-NEXT: cmoveq %rax, %rdi ; SSE2-NEXT: cmovneq %rax, %rsi ; SSE2-NEXT: movq %rsi, %rax ; SSE2-NEXT: shldq %cl, %rdi, %rax ; SSE2-NEXT: # kill: def $cl killed $cl killed $rcx ; SSE2-NEXT: shldq %cl, %rsi, %rdx ; SSE2-NEXT: retq ; ; SSE42-LABEL: fshl_i128_vector: ; SSE42: # %bb.0: ; SSE42-NEXT: movq %rdi, %rcx ; SSE42-NEXT: movq %xmm0, %rsi ; SSE42-NEXT: pextrq $1, %xmm0, %rdx ; SSE42-NEXT: movq %xmm1, %rdi ; SSE42-NEXT: pextrq $1, %xmm1, %rax ; SSE42-NEXT: testb $64, %cl ; SSE42-NEXT: cmovneq %rsi, %rdx ; SSE42-NEXT: cmoveq %rax, %rdi ; SSE42-NEXT: cmovneq %rax, %rsi ; SSE42-NEXT: movq %rsi, %rax ; SSE42-NEXT: shldq %cl, %rdi, %rax ; SSE42-NEXT: # kill: def $cl killed $cl killed $rcx ; SSE42-NEXT: shldq %cl, %rsi, %rdx ; SSE42-NEXT: retq ; ; AVX2-LABEL: fshl_i128_vector: ; AVX2: # %bb.0: ; AVX2-NEXT: movq %rdi, %rcx ; AVX2-NEXT: vmovq %xmm0, %rsi ; AVX2-NEXT: vpextrq $1, %xmm0, %rdx ; AVX2-NEXT: vpextrq $1, %xmm1, %rax ; AVX2-NEXT: vmovq %xmm1, %rdi ; AVX2-NEXT: testb $64, %cl ; AVX2-NEXT: cmovneq %rsi, %rdx ; AVX2-NEXT: cmoveq %rax, %rdi ; AVX2-NEXT: cmovneq %rax, %rsi ; AVX2-NEXT: movq %rsi, %rax ; AVX2-NEXT: shldq %cl, %rdi, %rax ; AVX2-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX2-NEXT: shldq %cl, %rsi, %rdx ; AVX2-NEXT: retq ; ; AVX512F-LABEL: fshl_i128_vector: ; AVX512F: # %bb.0: ; AVX512F-NEXT: movq %rdi, %rcx ; AVX512F-NEXT: vmovq %xmm0, %rsi ; AVX512F-NEXT: vpextrq $1, %xmm0, %rdx ; AVX512F-NEXT: vpextrq $1, %xmm1, %rax ; AVX512F-NEXT: vmovq %xmm1, %rdi ; AVX512F-NEXT: testb $64, %cl ; AVX512F-NEXT: cmovneq %rsi, %rdx ; AVX512F-NEXT: cmoveq %rax, %rdi ; AVX512F-NEXT: cmovneq %rax, %rsi ; AVX512F-NEXT: movq %rsi, %rax ; AVX512F-NEXT: shldq %cl, %rdi, %rax ; AVX512F-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX512F-NEXT: shldq %cl, %rsi, %rdx ; AVX512F-NEXT: retq ; ; AVX512VL-LABEL: fshl_i128_vector: ; AVX512VL: # %bb.0: ; AVX512VL-NEXT: movq %rdi, %rcx ; AVX512VL-NEXT: vpextrq $1, %xmm0, %rdx ; AVX512VL-NEXT: vmovq %xmm0, %rsi ; AVX512VL-NEXT: vmovq %xmm1, %rdi ; AVX512VL-NEXT: vpextrq $1, %xmm1, %rax ; AVX512VL-NEXT: testb $64, %cl ; AVX512VL-NEXT: cmovneq %rsi, %rdx ; AVX512VL-NEXT: cmoveq %rax, %rdi ; AVX512VL-NEXT: cmovneq %rax, %rsi ; AVX512VL-NEXT: movq %rsi, %rax ; AVX512VL-NEXT: shldq %cl, %rdi, %rax ; AVX512VL-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX512VL-NEXT: shldq %cl, %rsi, %rdx ; AVX512VL-NEXT: retq ; ; AVX512VBMI-LABEL: fshl_i128_vector: ; AVX512VBMI: # %bb.0: ; AVX512VBMI-NEXT: movq %rdi, %rcx ; AVX512VBMI-NEXT: vpextrq $1, %xmm0, %rdx ; AVX512VBMI-NEXT: vmovq %xmm0, %rsi ; AVX512VBMI-NEXT: vmovq %xmm1, %rdi ; AVX512VBMI-NEXT: vpextrq $1, %xmm1, %rax ; AVX512VBMI-NEXT: testb $64, %cl ; AVX512VBMI-NEXT: cmovneq %rsi, %rdx ; AVX512VBMI-NEXT: cmoveq %rax, %rdi ; AVX512VBMI-NEXT: cmovneq %rax, %rsi ; AVX512VBMI-NEXT: movq %rsi, %rax ; AVX512VBMI-NEXT: shldq %cl, %rdi, %rax ; AVX512VBMI-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX512VBMI-NEXT: shldq %cl, %rsi, %rdx ; AVX512VBMI-NEXT: retq %a0 = bitcast <2 x i64> %v0 to i128 %a1 = bitcast <2 x i64> %v1 to i128 %r = call i128 @llvm.fshl.i128(i128 %a0, i128 %a1, i128 %a2) ret i128 %r } define i128 @fshr_i128_vector(<2 x i64> %v0, <2 x i64> %v1, i128 %a2) nounwind { ; SSE2-LABEL: fshr_i128_vector: ; SSE2: # %bb.0: ; SSE2-NEXT: movq %rdi, %rcx ; SSE2-NEXT: movq %xmm0, %rdx ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] ; SSE2-NEXT: movq %xmm0, %rsi ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] ; SSE2-NEXT: movq %xmm0, %rdi ; SSE2-NEXT: testb $64, %cl ; SSE2-NEXT: cmoveq %rdx, %rsi ; SSE2-NEXT: cmoveq %rdi, %rdx ; SSE2-NEXT: movq %xmm1, %rax ; SSE2-NEXT: cmovneq %rdi, %rax ; SSE2-NEXT: shrdq %cl, %rdx, %rax ; SSE2-NEXT: # kill: def $cl killed $cl killed $rcx ; SSE2-NEXT: shrdq %cl, %rsi, %rdx ; SSE2-NEXT: retq ; ; SSE42-LABEL: fshr_i128_vector: ; SSE42: # %bb.0: ; SSE42-NEXT: movq %rdi, %rcx ; SSE42-NEXT: pextrq $1, %xmm0, %rsi ; SSE42-NEXT: movq %xmm0, %rdx ; SSE42-NEXT: pextrq $1, %xmm1, %rdi ; SSE42-NEXT: testb $64, %cl ; SSE42-NEXT: cmoveq %rdx, %rsi ; SSE42-NEXT: cmoveq %rdi, %rdx ; SSE42-NEXT: movq %xmm1, %rax ; SSE42-NEXT: cmovneq %rdi, %rax ; SSE42-NEXT: shrdq %cl, %rdx, %rax ; SSE42-NEXT: # kill: def $cl killed $cl killed $rcx ; SSE42-NEXT: shrdq %cl, %rsi, %rdx ; SSE42-NEXT: retq ; ; AVX2-LABEL: fshr_i128_vector: ; AVX2: # %bb.0: ; AVX2-NEXT: movq %rdi, %rcx ; AVX2-NEXT: vmovq %xmm0, %rdx ; AVX2-NEXT: vpextrq $1, %xmm0, %rsi ; AVX2-NEXT: vpextrq $1, %xmm1, %rdi ; AVX2-NEXT: vmovq %xmm1, %rax ; AVX2-NEXT: testb $64, %cl ; AVX2-NEXT: cmoveq %rdx, %rsi ; AVX2-NEXT: cmoveq %rdi, %rdx ; AVX2-NEXT: cmovneq %rdi, %rax ; AVX2-NEXT: shrdq %cl, %rdx, %rax ; AVX2-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX2-NEXT: shrdq %cl, %rsi, %rdx ; AVX2-NEXT: retq ; ; AVX512F-LABEL: fshr_i128_vector: ; AVX512F: # %bb.0: ; AVX512F-NEXT: movq %rdi, %rcx ; AVX512F-NEXT: vmovq %xmm0, %rdx ; AVX512F-NEXT: vpextrq $1, %xmm0, %rsi ; AVX512F-NEXT: vpextrq $1, %xmm1, %rdi ; AVX512F-NEXT: vmovq %xmm1, %rax ; AVX512F-NEXT: testb $64, %cl ; AVX512F-NEXT: cmoveq %rdx, %rsi ; AVX512F-NEXT: cmoveq %rdi, %rdx ; AVX512F-NEXT: cmovneq %rdi, %rax ; AVX512F-NEXT: shrdq %cl, %rdx, %rax ; AVX512F-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX512F-NEXT: shrdq %cl, %rsi, %rdx ; AVX512F-NEXT: retq ; ; AVX512VL-LABEL: fshr_i128_vector: ; AVX512VL: # %bb.0: ; AVX512VL-NEXT: movq %rdi, %rcx ; AVX512VL-NEXT: vpextrq $1, %xmm0, %rsi ; AVX512VL-NEXT: vmovq %xmm0, %rdx ; AVX512VL-NEXT: vmovq %xmm1, %rax ; AVX512VL-NEXT: vpextrq $1, %xmm1, %rdi ; AVX512VL-NEXT: testb $64, %cl ; AVX512VL-NEXT: cmoveq %rdx, %rsi ; AVX512VL-NEXT: cmoveq %rdi, %rdx ; AVX512VL-NEXT: cmovneq %rdi, %rax ; AVX512VL-NEXT: shrdq %cl, %rdx, %rax ; AVX512VL-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX512VL-NEXT: shrdq %cl, %rsi, %rdx ; AVX512VL-NEXT: retq ; ; AVX512VBMI-LABEL: fshr_i128_vector: ; AVX512VBMI: # %bb.0: ; AVX512VBMI-NEXT: movq %rdi, %rcx ; AVX512VBMI-NEXT: vpextrq $1, %xmm0, %rsi ; AVX512VBMI-NEXT: vmovq %xmm0, %rdx ; AVX512VBMI-NEXT: vmovq %xmm1, %rax ; AVX512VBMI-NEXT: vpextrq $1, %xmm1, %rdi ; AVX512VBMI-NEXT: testb $64, %cl ; AVX512VBMI-NEXT: cmoveq %rdx, %rsi ; AVX512VBMI-NEXT: cmoveq %rdi, %rdx ; AVX512VBMI-NEXT: cmovneq %rdi, %rax ; AVX512VBMI-NEXT: shrdq %cl, %rdx, %rax ; AVX512VBMI-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX512VBMI-NEXT: shrdq %cl, %rsi, %rdx ; AVX512VBMI-NEXT: retq %a0 = bitcast <2 x i64> %v0 to i128 %a1 = bitcast <2 x i64> %v1 to i128 %r = call i128 @llvm.fshr.i128(i128 %a0, i128 %a1, i128 %a2) ret i128 %r } define i128 @fshl_rot_i128_vector(<2 x i64> %v0, i128 %a2) nounwind { ; SSE2-LABEL: fshl_rot_i128_vector: ; SSE2: # %bb.0: ; SSE2-NEXT: movq %rdi, %rcx ; SSE2-NEXT: movq %xmm0, %rsi ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] ; SSE2-NEXT: movq %xmm0, %rax ; SSE2-NEXT: testb $64, %cl ; SSE2-NEXT: movq %rax, %rdx ; SSE2-NEXT: cmovneq %rsi, %rdx ; SSE2-NEXT: cmovneq %rax, %rsi ; SSE2-NEXT: movq %rsi, %rax ; SSE2-NEXT: shldq %cl, %rdx, %rax ; SSE2-NEXT: # kill: def $cl killed $cl killed $rcx ; SSE2-NEXT: shldq %cl, %rsi, %rdx ; SSE2-NEXT: retq ; ; SSE42-LABEL: fshl_rot_i128_vector: ; SSE42: # %bb.0: ; SSE42-NEXT: movq %rdi, %rcx ; SSE42-NEXT: movq %xmm0, %rsi ; SSE42-NEXT: pextrq $1, %xmm0, %rax ; SSE42-NEXT: testb $64, %cl ; SSE42-NEXT: movq %rax, %rdx ; SSE42-NEXT: cmovneq %rsi, %rdx ; SSE42-NEXT: cmovneq %rax, %rsi ; SSE42-NEXT: movq %rsi, %rax ; SSE42-NEXT: shldq %cl, %rdx, %rax ; SSE42-NEXT: # kill: def $cl killed $cl killed $rcx ; SSE42-NEXT: shldq %cl, %rsi, %rdx ; SSE42-NEXT: retq ; ; AVX-LABEL: fshl_rot_i128_vector: ; AVX: # %bb.0: ; AVX-NEXT: movq %rdi, %rcx ; AVX-NEXT: vmovq %xmm0, %rsi ; AVX-NEXT: vpextrq $1, %xmm0, %rax ; AVX-NEXT: testb $64, %cl ; AVX-NEXT: movq %rax, %rdx ; AVX-NEXT: cmovneq %rsi, %rdx ; AVX-NEXT: cmovneq %rax, %rsi ; AVX-NEXT: movq %rsi, %rax ; AVX-NEXT: shldq %cl, %rdx, %rax ; AVX-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX-NEXT: shldq %cl, %rsi, %rdx ; AVX-NEXT: retq %a0 = bitcast <2 x i64> %v0 to i128 %r = call i128 @llvm.fshl.i128(i128 %a0, i128 %a0, i128 %a2) ret i128 %r } define i128 @fshr_rot_i128_vector(<2 x i64> %v0, i128 %a2) nounwind { ; SSE2-LABEL: fshr_rot_i128_vector: ; SSE2: # %bb.0: ; SSE2-NEXT: movq %rdi, %rcx ; SSE2-NEXT: movq %xmm0, %rax ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] ; SSE2-NEXT: movq %xmm0, %rsi ; SSE2-NEXT: testb $64, %cl ; SSE2-NEXT: movq %rax, %rdx ; SSE2-NEXT: cmoveq %rsi, %rdx ; SSE2-NEXT: cmoveq %rax, %rsi ; SSE2-NEXT: movq %rsi, %rax ; SSE2-NEXT: shrdq %cl, %rdx, %rax ; SSE2-NEXT: # kill: def $cl killed $cl killed $rcx ; SSE2-NEXT: shrdq %cl, %rsi, %rdx ; SSE2-NEXT: retq ; ; SSE42-LABEL: fshr_rot_i128_vector: ; SSE42: # %bb.0: ; SSE42-NEXT: movq %rdi, %rcx ; SSE42-NEXT: pextrq $1, %xmm0, %rsi ; SSE42-NEXT: movq %xmm0, %rax ; SSE42-NEXT: testb $64, %cl ; SSE42-NEXT: movq %rax, %rdx ; SSE42-NEXT: cmoveq %rsi, %rdx ; SSE42-NEXT: cmoveq %rax, %rsi ; SSE42-NEXT: movq %rsi, %rax ; SSE42-NEXT: shrdq %cl, %rdx, %rax ; SSE42-NEXT: # kill: def $cl killed $cl killed $rcx ; SSE42-NEXT: shrdq %cl, %rsi, %rdx ; SSE42-NEXT: retq ; ; AVX-LABEL: fshr_rot_i128_vector: ; AVX: # %bb.0: ; AVX-NEXT: movq %rdi, %rcx ; AVX-NEXT: vpextrq $1, %xmm0, %rsi ; AVX-NEXT: vmovq %xmm0, %rax ; AVX-NEXT: testb $64, %cl ; AVX-NEXT: movq %rax, %rdx ; AVX-NEXT: cmoveq %rsi, %rdx ; AVX-NEXT: cmoveq %rax, %rsi ; AVX-NEXT: movq %rsi, %rax ; AVX-NEXT: shrdq %cl, %rdx, %rax ; AVX-NEXT: # kill: def $cl killed $cl killed $rcx ; AVX-NEXT: shrdq %cl, %rsi, %rdx ; AVX-NEXT: retq %a0 = bitcast <2 x i64> %v0 to i128 %r = call i128 @llvm.fshr.i128(i128 %a0, i128 %a0, i128 %a2) ret i128 %r } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: ; AVX512: {{.*}}