1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=X64 3; RUN: llc < %s -mtriple=i686 -mattr=cmov | FileCheck %s --check-prefix=X86 4 5declare i4 @llvm.ushl.sat.i4 (i4, i4) 6declare i8 @llvm.ushl.sat.i8 (i8, i8) 7declare i15 @llvm.ushl.sat.i15 (i15, i15) 8declare i16 @llvm.ushl.sat.i16 (i16, i16) 9declare i18 @llvm.ushl.sat.i18 (i18, i18) 10declare i32 @llvm.ushl.sat.i32 (i32, i32) 11declare i64 @llvm.ushl.sat.i64 (i64, i64) 12 13define i16 @func(i16 %x, i16 %y) nounwind { 14; X64-LABEL: func: 15; X64: # %bb.0: 16; X64-NEXT: movl %esi, %ecx 17; X64-NEXT: movl %edi, %edx 18; X64-NEXT: shll %cl, %edx 19; X64-NEXT: movzwl %dx, %eax 20; X64-NEXT: # kill: def $cl killed $cl killed $ecx 21; X64-NEXT: shrl %cl, %eax 22; X64-NEXT: cmpw %ax, %di 23; X64-NEXT: movl $65535, %eax # imm = 0xFFFF 24; X64-NEXT: cmovel %edx, %eax 25; X64-NEXT: # kill: def $ax killed $ax killed $eax 26; X64-NEXT: retq 27; 28; X86-LABEL: func: 29; X86: # %bb.0: 30; X86-NEXT: pushl %esi 31; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 32; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 33; X86-NEXT: movl %eax, %edx 34; X86-NEXT: shll %cl, %edx 35; X86-NEXT: movzwl %dx, %esi 36; X86-NEXT: shrl %cl, %esi 37; X86-NEXT: cmpw %si, %ax 38; X86-NEXT: movl $65535, %eax # imm = 0xFFFF 39; X86-NEXT: cmovel %edx, %eax 40; X86-NEXT: # kill: def $ax killed $ax killed $eax 41; X86-NEXT: popl %esi 42; X86-NEXT: retl 43 %tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 %y) 44 ret i16 %tmp 45} 46 47define i16 @func2(i8 %x, i8 %y) nounwind { 48; X64-LABEL: func2: 49; X64: # %bb.0: 50; X64-NEXT: movl %esi, %ecx 51; X64-NEXT: movsbl %dil, %eax 52; X64-NEXT: addl %eax, %eax 53; X64-NEXT: movl %eax, %edx 54; X64-NEXT: shll %cl, %edx 55; X64-NEXT: movzwl %dx, %esi 56; X64-NEXT: # kill: def $cl killed $cl killed $ecx 57; X64-NEXT: shrl %cl, %esi 58; X64-NEXT: cmpw %si, %ax 59; X64-NEXT: movl $65535, %eax # imm = 0xFFFF 60; X64-NEXT: cmovel %edx, %eax 61; X64-NEXT: cwtl 62; X64-NEXT: shrl %eax 63; X64-NEXT: # kill: def $ax killed $ax killed $eax 64; X64-NEXT: retq 65; 66; X86-LABEL: func2: 67; X86: # %bb.0: 68; X86-NEXT: pushl %esi 69; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 70; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax 71; X86-NEXT: addl %eax, %eax 72; X86-NEXT: movl %eax, %edx 73; X86-NEXT: shll %cl, %edx 74; X86-NEXT: movzwl %dx, %esi 75; X86-NEXT: shrl %cl, %esi 76; X86-NEXT: cmpw %si, %ax 77; X86-NEXT: movl $65535, %eax # imm = 0xFFFF 78; X86-NEXT: cmovel %edx, %eax 79; X86-NEXT: cwtl 80; X86-NEXT: shrl %eax 81; X86-NEXT: # kill: def $ax killed $ax killed $eax 82; X86-NEXT: popl %esi 83; X86-NEXT: retl 84 %x2 = sext i8 %x to i15 85 %y2 = sext i8 %y to i15 86 %tmp = call i15 @llvm.ushl.sat.i15(i15 %x2, i15 %y2) 87 %tmp2 = sext i15 %tmp to i16 88 ret i16 %tmp2 89} 90 91define i16 @func3(i15 %x, i8 %y) nounwind { 92; X64-LABEL: func3: 93; X64: # %bb.0: 94; X64-NEXT: movl %esi, %ecx 95; X64-NEXT: shll $7, %ecx 96; X64-NEXT: addl %edi, %edi 97; X64-NEXT: movl %edi, %eax 98; X64-NEXT: shll %cl, %eax 99; X64-NEXT: movzwl %ax, %edx 100; X64-NEXT: # kill: def $cl killed $cl killed $ecx 101; X64-NEXT: shrl %cl, %edx 102; X64-NEXT: cmpw %dx, %di 103; X64-NEXT: movl $65535, %ecx # imm = 0xFFFF 104; X64-NEXT: cmovel %eax, %ecx 105; X64-NEXT: movswl %cx, %eax 106; X64-NEXT: shrl %eax 107; X64-NEXT: # kill: def $ax killed $ax killed $eax 108; X64-NEXT: retq 109; 110; X86-LABEL: func3: 111; X86: # %bb.0: 112; X86-NEXT: pushl %esi 113; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 114; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 115; X86-NEXT: shll $7, %ecx 116; X86-NEXT: addl %eax, %eax 117; X86-NEXT: movl %eax, %edx 118; X86-NEXT: shll %cl, %edx 119; X86-NEXT: movzwl %dx, %esi 120; X86-NEXT: # kill: def $cl killed $cl killed $ecx 121; X86-NEXT: shrl %cl, %esi 122; X86-NEXT: cmpw %si, %ax 123; X86-NEXT: movl $65535, %eax # imm = 0xFFFF 124; X86-NEXT: cmovel %edx, %eax 125; X86-NEXT: cwtl 126; X86-NEXT: shrl %eax 127; X86-NEXT: # kill: def $ax killed $ax killed $eax 128; X86-NEXT: popl %esi 129; X86-NEXT: retl 130 %y2 = sext i8 %y to i15 131 %y3 = shl i15 %y2, 7 132 %tmp = call i15 @llvm.ushl.sat.i15(i15 %x, i15 %y3) 133 %tmp2 = sext i15 %tmp to i16 134 ret i16 %tmp2 135} 136 137define i4 @func4(i4 %x, i4 %y) nounwind { 138; X64-LABEL: func4: 139; X64: # %bb.0: 140; X64-NEXT: movl %esi, %ecx 141; X64-NEXT: andb $15, %cl 142; X64-NEXT: shlb $4, %dil 143; X64-NEXT: movl %edi, %eax 144; X64-NEXT: shlb %cl, %al 145; X64-NEXT: movzbl %al, %edx 146; X64-NEXT: movl %edx, %eax 147; X64-NEXT: # kill: def $cl killed $cl killed $ecx 148; X64-NEXT: shrb %cl, %al 149; X64-NEXT: cmpb %al, %dil 150; X64-NEXT: movl $255, %eax 151; X64-NEXT: cmovel %edx, %eax 152; X64-NEXT: shrb $4, %al 153; X64-NEXT: # kill: def $al killed $al killed $eax 154; X64-NEXT: retq 155; 156; X86-LABEL: func4: 157; X86: # %bb.0: 158; X86-NEXT: pushl %esi 159; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 160; X86-NEXT: andb $15, %cl 161; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 162; X86-NEXT: shlb $4, %al 163; X86-NEXT: movl %eax, %edx 164; X86-NEXT: shlb %cl, %dl 165; X86-NEXT: movzbl %dl, %esi 166; X86-NEXT: shrb %cl, %dl 167; X86-NEXT: cmpb %dl, %al 168; X86-NEXT: movl $255, %eax 169; X86-NEXT: cmovel %esi, %eax 170; X86-NEXT: shrb $4, %al 171; X86-NEXT: # kill: def $al killed $al killed $eax 172; X86-NEXT: popl %esi 173; X86-NEXT: retl 174 %tmp = call i4 @llvm.ushl.sat.i4(i4 %x, i4 %y) 175 ret i4 %tmp 176} 177 178define i64 @func5(i64 %x, i64 %y) nounwind { 179; X64-LABEL: func5: 180; X64: # %bb.0: 181; X64-NEXT: movq %rsi, %rcx 182; X64-NEXT: movq %rdi, %rdx 183; X64-NEXT: shlq %cl, %rdx 184; X64-NEXT: movq %rdx, %rax 185; X64-NEXT: # kill: def $cl killed $cl killed $rcx 186; X64-NEXT: shrq %cl, %rax 187; X64-NEXT: cmpq %rax, %rdi 188; X64-NEXT: movq $-1, %rax 189; X64-NEXT: cmoveq %rdx, %rax 190; X64-NEXT: retq 191; 192; X86-LABEL: func5: 193; X86: # %bb.0: 194; X86-NEXT: pushl %ebp 195; X86-NEXT: pushl %ebx 196; X86-NEXT: pushl %edi 197; X86-NEXT: pushl %esi 198; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 199; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 200; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 201; X86-NEXT: movl %esi, %edi 202; X86-NEXT: shll %cl, %edi 203; X86-NEXT: shldl %cl, %esi, %edx 204; X86-NEXT: xorl %ebx, %ebx 205; X86-NEXT: testb $32, %cl 206; X86-NEXT: cmovnel %edi, %edx 207; X86-NEXT: cmovnel %ebx, %edi 208; X86-NEXT: movl %edx, %ebp 209; X86-NEXT: shrl %cl, %ebp 210; X86-NEXT: testb $32, %cl 211; X86-NEXT: cmovel %ebp, %ebx 212; X86-NEXT: movl %edi, %eax 213; X86-NEXT: shrdl %cl, %edx, %eax 214; X86-NEXT: testb $32, %cl 215; X86-NEXT: cmovnel %ebp, %eax 216; X86-NEXT: xorl %esi, %eax 217; X86-NEXT: xorl {{[0-9]+}}(%esp), %ebx 218; X86-NEXT: orl %eax, %ebx 219; X86-NEXT: movl $-1, %eax 220; X86-NEXT: cmovnel %eax, %edi 221; X86-NEXT: cmovnel %eax, %edx 222; X86-NEXT: movl %edi, %eax 223; X86-NEXT: popl %esi 224; X86-NEXT: popl %edi 225; X86-NEXT: popl %ebx 226; X86-NEXT: popl %ebp 227; X86-NEXT: retl 228 %tmp = call i64 @llvm.ushl.sat.i64(i64 %x, i64 %y) 229 ret i64 %tmp 230} 231 232define i18 @func6(i16 %x, i16 %y) nounwind { 233; X64-LABEL: func6: 234; X64: # %bb.0: 235; X64-NEXT: movl %esi, %ecx 236; X64-NEXT: movswl %di, %eax 237; X64-NEXT: shll $14, %eax 238; X64-NEXT: movl %eax, %edx 239; X64-NEXT: shll %cl, %edx 240; X64-NEXT: movl %edx, %esi 241; X64-NEXT: # kill: def $cl killed $cl killed $ecx 242; X64-NEXT: shrl %cl, %esi 243; X64-NEXT: cmpl %esi, %eax 244; X64-NEXT: movl $-1, %eax 245; X64-NEXT: cmovel %edx, %eax 246; X64-NEXT: shrl $14, %eax 247; X64-NEXT: retq 248; 249; X86-LABEL: func6: 250; X86: # %bb.0: 251; X86-NEXT: pushl %esi 252; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 253; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax 254; X86-NEXT: shll $14, %eax 255; X86-NEXT: movl %eax, %edx 256; X86-NEXT: shll %cl, %edx 257; X86-NEXT: movl %edx, %esi 258; X86-NEXT: shrl %cl, %esi 259; X86-NEXT: cmpl %esi, %eax 260; X86-NEXT: movl $-1, %eax 261; X86-NEXT: cmovel %edx, %eax 262; X86-NEXT: shrl $14, %eax 263; X86-NEXT: popl %esi 264; X86-NEXT: retl 265 %x2 = sext i16 %x to i18 266 %y2 = sext i16 %y to i18 267 %tmp = call i18 @llvm.ushl.sat.i18(i18 %x2, i18 %y2) 268 ret i18 %tmp 269} 270 271define i32 @func7(i32 %x, i32 %y) nounwind { 272; X64-LABEL: func7: 273; X64: # %bb.0: 274; X64-NEXT: movl %esi, %ecx 275; X64-NEXT: movl %edi, %edx 276; X64-NEXT: shll %cl, %edx 277; X64-NEXT: movl %edx, %eax 278; X64-NEXT: # kill: def $cl killed $cl killed $ecx 279; X64-NEXT: shrl %cl, %eax 280; X64-NEXT: cmpl %eax, %edi 281; X64-NEXT: movl $-1, %eax 282; X64-NEXT: cmovel %edx, %eax 283; X64-NEXT: retq 284; 285; X86-LABEL: func7: 286; X86: # %bb.0: 287; X86-NEXT: pushl %esi 288; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 289; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 290; X86-NEXT: movl %eax, %edx 291; X86-NEXT: shll %cl, %edx 292; X86-NEXT: movl %edx, %esi 293; X86-NEXT: shrl %cl, %esi 294; X86-NEXT: cmpl %esi, %eax 295; X86-NEXT: movl $-1, %eax 296; X86-NEXT: cmovel %edx, %eax 297; X86-NEXT: popl %esi 298; X86-NEXT: retl 299 %tmp = call i32 @llvm.ushl.sat.i32(i32 %x, i32 %y) 300 ret i32 %tmp 301} 302 303define i8 @func8(i8 %x, i8 %y) nounwind { 304; X64-LABEL: func8: 305; X64: # %bb.0: 306; X64-NEXT: movl %esi, %ecx 307; X64-NEXT: movl %edi, %eax 308; X64-NEXT: shlb %cl, %al 309; X64-NEXT: movzbl %al, %edx 310; X64-NEXT: movl %edx, %eax 311; X64-NEXT: # kill: def $cl killed $cl killed $ecx 312; X64-NEXT: shrb %cl, %al 313; X64-NEXT: cmpb %al, %dil 314; X64-NEXT: movl $255, %eax 315; X64-NEXT: cmovel %edx, %eax 316; X64-NEXT: # kill: def $al killed $al killed $eax 317; X64-NEXT: retq 318; 319; X86-LABEL: func8: 320; X86: # %bb.0: 321; X86-NEXT: pushl %esi 322; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 323; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 324; X86-NEXT: movl %eax, %edx 325; X86-NEXT: shlb %cl, %dl 326; X86-NEXT: movzbl %dl, %esi 327; X86-NEXT: shrb %cl, %dl 328; X86-NEXT: cmpb %dl, %al 329; X86-NEXT: movl $255, %eax 330; X86-NEXT: cmovel %esi, %eax 331; X86-NEXT: # kill: def $al killed $al killed $eax 332; X86-NEXT: popl %esi 333; X86-NEXT: retl 334 %tmp = call i8 @llvm.ushl.sat.i8(i8 %x, i8 %y) 335 ret i8 %tmp 336} 337