1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s 3 4; (zext(select c, load1, load2)) -> (select c, zextload1, zextload2) 5define i64 @zext_scalar(i8* %p, i1 zeroext %c) { 6; CHECK-LABEL: zext_scalar: 7; CHECK: # %bb.0: 8; CHECK-NEXT: movzbl (%rdi), %ecx 9; CHECK-NEXT: movzbl 1(%rdi), %eax 10; CHECK-NEXT: testl %esi, %esi 11; CHECK-NEXT: cmoveq %rcx, %rax 12; CHECK-NEXT: retq 13 %ld1 = load volatile i8, i8* %p 14 %arrayidx1 = getelementptr inbounds i8, i8* %p, i64 1 15 %ld2 = load volatile i8, i8* %arrayidx1 16 %cond.v = select i1 %c, i8 %ld2, i8 %ld1 17 %cond = zext i8 %cond.v to i64 18 ret i64 %cond 19} 20 21define i64 @zext_scalar2(i8* %p, i16* %q, i1 zeroext %c) { 22; CHECK-LABEL: zext_scalar2: 23; CHECK: # %bb.0: 24; CHECK-NEXT: movzbl (%rdi), %ecx 25; CHECK-NEXT: movzwl (%rsi), %eax 26; CHECK-NEXT: testl %edx, %edx 27; CHECK-NEXT: cmoveq %rcx, %rax 28; CHECK-NEXT: retq 29 %ld1 = load volatile i8, i8* %p 30 %ext_ld1 = zext i8 %ld1 to i16 31 %ld2 = load volatile i16, i16* %q 32 %cond.v = select i1 %c, i16 %ld2, i16 %ext_ld1 33 %cond = zext i16 %cond.v to i64 34 ret i64 %cond 35} 36 37; Don't fold the ext if there is a load with conflicting ext type. 38define i64 @zext_scalar_neg(i8* %p, i16* %q, i1 zeroext %c) { 39; CHECK-LABEL: zext_scalar_neg: 40; CHECK: # %bb.0: 41; CHECK-NEXT: movsbl (%rdi), %eax 42; CHECK-NEXT: testl %edx, %edx 43; CHECK-NEXT: je .LBB2_2 44; CHECK-NEXT: # %bb.1: 45; CHECK-NEXT: movzwl (%rsi), %eax 46; CHECK-NEXT: .LBB2_2: 47; CHECK-NEXT: movzwl %ax, %eax 48; CHECK-NEXT: retq 49 %ld1 = load volatile i8, i8* %p 50 %ext_ld1 = sext i8 %ld1 to i16 51 %ld2 = load volatile i16, i16* %q 52 %cond.v = select i1 %c, i16 %ld2, i16 %ext_ld1 53 %cond = zext i16 %cond.v to i64 54 ret i64 %cond 55} 56 57; (sext(select c, load1, load2)) -> (select c, sextload1, sextload2) 58define i64 @sext_scalar(i8* %p, i1 zeroext %c) { 59; CHECK-LABEL: sext_scalar: 60; CHECK: # %bb.0: 61; CHECK-NEXT: movsbq (%rdi), %rcx 62; CHECK-NEXT: movsbq 1(%rdi), %rax 63; CHECK-NEXT: testl %esi, %esi 64; CHECK-NEXT: cmoveq %rcx, %rax 65; CHECK-NEXT: retq 66 %ld1 = load volatile i8, i8* %p 67 %arrayidx1 = getelementptr inbounds i8, i8* %p, i64 1 68 %ld2 = load volatile i8, i8* %arrayidx1 69 %cond.v = select i1 %c, i8 %ld2, i8 %ld1 70 %cond = sext i8 %cond.v to i64 71 ret i64 %cond 72} 73 74; Same as zext_scalar, but operate on vectors. 75define <2 x i64> @zext_vector_i1(<2 x i32>* %p, i1 zeroext %c) { 76; CHECK-LABEL: zext_vector_i1: 77; CHECK: # %bb.0: 78; CHECK-NEXT: pmovzxdq {{.*#+}} xmm1 = mem[0],zero,mem[1],zero 79; CHECK-NEXT: pmovzxdq {{.*#+}} xmm0 = mem[0],zero,mem[1],zero 80; CHECK-NEXT: testl %esi, %esi 81; CHECK-NEXT: jne .LBB4_2 82; CHECK-NEXT: # %bb.1: 83; CHECK-NEXT: movdqa %xmm1, %xmm0 84; CHECK-NEXT: .LBB4_2: 85; CHECK-NEXT: retq 86 %ld1 = load volatile <2 x i32>, <2 x i32>* %p 87 %arrayidx1 = getelementptr inbounds <2 x i32>, <2 x i32>* %p, i64 1 88 %ld2 = load volatile <2 x i32>, <2 x i32>* %arrayidx1 89 %cond.v = select i1 %c, <2 x i32> %ld2, <2 x i32> %ld1 90 %cond = zext <2 x i32> %cond.v to <2 x i64> 91 ret <2 x i64> %cond 92} 93 94define <2 x i64> @zext_vector_v2i1(<2 x i32>* %p, <2 x i1> %c) { 95; CHECK-LABEL: zext_vector_v2i1: 96; CHECK: # %bb.0: 97; CHECK-NEXT: psllq $63, %xmm0 98; CHECK-NEXT: pmovzxdq {{.*#+}} xmm1 = mem[0],zero,mem[1],zero 99; CHECK-NEXT: pmovzxdq {{.*#+}} xmm2 = mem[0],zero,mem[1],zero 100; CHECK-NEXT: blendvpd %xmm0, %xmm2, %xmm1 101; CHECK-NEXT: movapd %xmm1, %xmm0 102; CHECK-NEXT: retq 103 %ld1 = load volatile <2 x i32>, <2 x i32>* %p 104 %arrayidx1 = getelementptr inbounds <2 x i32>, <2 x i32>* %p, i64 1 105 %ld2 = load volatile <2 x i32>, <2 x i32>* %arrayidx1 106 %cond.v = select <2 x i1> %c, <2 x i32> %ld2, <2 x i32> %ld1 107 %cond = zext <2 x i32> %cond.v to <2 x i64> 108 ret <2 x i64> %cond 109} 110 111; Same as sext_scalar, but operate on vectors. 112define <2 x i64> @sext_vector_i1(<2 x i32>* %p, i1 zeroext %c) { 113; CHECK-LABEL: sext_vector_i1: 114; CHECK: # %bb.0: 115; CHECK-NEXT: pmovsxdq (%rdi), %xmm1 116; CHECK-NEXT: pmovsxdq 8(%rdi), %xmm0 117; CHECK-NEXT: testl %esi, %esi 118; CHECK-NEXT: jne .LBB6_2 119; CHECK-NEXT: # %bb.1: 120; CHECK-NEXT: movdqa %xmm1, %xmm0 121; CHECK-NEXT: .LBB6_2: 122; CHECK-NEXT: retq 123 %ld1 = load volatile <2 x i32>, <2 x i32>* %p 124 %arrayidx1 = getelementptr inbounds <2 x i32>, <2 x i32>* %p, i64 1 125 %ld2 = load volatile <2 x i32>, <2 x i32>* %arrayidx1 126 %cond.v = select i1 %c, <2 x i32> %ld2, <2 x i32> %ld1 127 %cond = sext <2 x i32> %cond.v to <2 x i64> 128 ret <2 x i64> %cond 129} 130 131define <2 x i64> @sext_vector_v2i1(<2 x i32>* %p, <2 x i1> %c) { 132; CHECK-LABEL: sext_vector_v2i1: 133; CHECK: # %bb.0: 134; CHECK-NEXT: psllq $63, %xmm0 135; CHECK-NEXT: pmovsxdq (%rdi), %xmm1 136; CHECK-NEXT: pmovsxdq 8(%rdi), %xmm2 137; CHECK-NEXT: blendvpd %xmm0, %xmm2, %xmm1 138; CHECK-NEXT: movapd %xmm1, %xmm0 139; CHECK-NEXT: retq 140 %ld1 = load volatile <2 x i32>, <2 x i32>* %p 141 %arrayidx1 = getelementptr inbounds <2 x i32>, <2 x i32>* %p, i64 1 142 %ld2 = load volatile <2 x i32>, <2 x i32>* %arrayidx1 143 %cond.v = select <2 x i1> %c, <2 x i32> %ld2, <2 x i32> %ld1 144 %cond = sext <2 x i32> %cond.v to <2 x i64> 145 ret <2 x i64> %cond 146} 147