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.sshl.sat.i4 (i4, i4) 6declare i8 @llvm.sshl.sat.i8 (i8, i8) 7declare i15 @llvm.sshl.sat.i15 (i15, i15) 8declare i16 @llvm.sshl.sat.i16 (i16, i16) 9declare i18 @llvm.sshl.sat.i18 (i18, i18) 10declare i32 @llvm.sshl.sat.i32 (i32, i32) 11declare i64 @llvm.sshl.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: movswl %dx, %esi 20; X64-NEXT: # kill: def $cl killed $cl killed $ecx 21; X64-NEXT: sarl %cl, %esi 22; X64-NEXT: xorl %eax, %eax 23; X64-NEXT: testw %di, %di 24; X64-NEXT: sets %al 25; X64-NEXT: addl $32767, %eax # imm = 0x7FFF 26; X64-NEXT: cmpw %si, %di 27; X64-NEXT: cmovel %edx, %eax 28; X64-NEXT: # kill: def $ax killed $ax killed $eax 29; X64-NEXT: retq 30; 31; X86-LABEL: func: 32; X86: # %bb.0: 33; X86-NEXT: pushl %edi 34; X86-NEXT: pushl %esi 35; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 36; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 37; X86-NEXT: movl %edx, %esi 38; X86-NEXT: shll %cl, %esi 39; X86-NEXT: movswl %si, %edi 40; X86-NEXT: sarl %cl, %edi 41; X86-NEXT: xorl %eax, %eax 42; X86-NEXT: testw %dx, %dx 43; X86-NEXT: sets %al 44; X86-NEXT: addl $32767, %eax # imm = 0x7FFF 45; X86-NEXT: cmpw %di, %dx 46; X86-NEXT: cmovel %esi, %eax 47; X86-NEXT: # kill: def $ax killed $ax killed $eax 48; X86-NEXT: popl %esi 49; X86-NEXT: popl %edi 50; X86-NEXT: retl 51 %tmp = call i16 @llvm.sshl.sat.i16(i16 %x, i16 %y) 52 ret i16 %tmp 53} 54 55define i16 @func2(i8 %x, i8 %y) nounwind { 56; X64-LABEL: func2: 57; X64: # %bb.0: 58; X64-NEXT: movl %esi, %ecx 59; X64-NEXT: movsbl %dil, %eax 60; X64-NEXT: addl %eax, %eax 61; X64-NEXT: xorl %edx, %edx 62; X64-NEXT: testw %ax, %ax 63; X64-NEXT: sets %dl 64; X64-NEXT: addl $32767, %edx # imm = 0x7FFF 65; X64-NEXT: movl %eax, %esi 66; X64-NEXT: shll %cl, %esi 67; X64-NEXT: movswl %si, %edi 68; X64-NEXT: # kill: def $cl killed $cl killed $ecx 69; X64-NEXT: sarl %cl, %edi 70; X64-NEXT: cmpw %di, %ax 71; X64-NEXT: cmovnel %edx, %esi 72; X64-NEXT: movswl %si, %eax 73; X64-NEXT: shrl %eax 74; X64-NEXT: # kill: def $ax killed $ax killed $eax 75; X64-NEXT: retq 76; 77; X86-LABEL: func2: 78; X86: # %bb.0: 79; X86-NEXT: pushl %esi 80; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 81; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax 82; X86-NEXT: addl %eax, %eax 83; X86-NEXT: movl %eax, %edx 84; X86-NEXT: shll %cl, %edx 85; X86-NEXT: movswl %dx, %esi 86; X86-NEXT: sarl %cl, %esi 87; X86-NEXT: xorl %ecx, %ecx 88; X86-NEXT: testw %ax, %ax 89; X86-NEXT: sets %cl 90; X86-NEXT: addl $32767, %ecx # imm = 0x7FFF 91; X86-NEXT: cmpw %si, %ax 92; X86-NEXT: cmovel %edx, %ecx 93; X86-NEXT: movswl %cx, %eax 94; X86-NEXT: shrl %eax 95; X86-NEXT: # kill: def $ax killed $ax killed $eax 96; X86-NEXT: popl %esi 97; X86-NEXT: retl 98 %x2 = sext i8 %x to i15 99 %y2 = sext i8 %y to i15 100 %tmp = call i15 @llvm.sshl.sat.i15(i15 %x2, i15 %y2) 101 %tmp2 = sext i15 %tmp to i16 102 ret i16 %tmp2 103} 104 105define i16 @func3(i15 %x, i8 %y) nounwind { 106; X64-LABEL: func3: 107; X64: # %bb.0: 108; X64-NEXT: movl %esi, %ecx 109; X64-NEXT: shll $7, %ecx 110; X64-NEXT: addl %edi, %edi 111; X64-NEXT: movl %edi, %eax 112; X64-NEXT: shll %cl, %eax 113; X64-NEXT: movswl %ax, %edx 114; X64-NEXT: # kill: def $cl killed $cl killed $ecx 115; X64-NEXT: sarl %cl, %edx 116; X64-NEXT: xorl %ecx, %ecx 117; X64-NEXT: testw %di, %di 118; X64-NEXT: sets %cl 119; X64-NEXT: addl $32767, %ecx # imm = 0x7FFF 120; X64-NEXT: cmpw %dx, %di 121; X64-NEXT: cmovel %eax, %ecx 122; X64-NEXT: movswl %cx, %eax 123; X64-NEXT: shrl %eax 124; X64-NEXT: # kill: def $ax killed $ax killed $eax 125; X64-NEXT: retq 126; 127; X86-LABEL: func3: 128; X86: # %bb.0: 129; X86-NEXT: pushl %esi 130; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 131; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 132; X86-NEXT: shll $7, %ecx 133; X86-NEXT: addl %eax, %eax 134; X86-NEXT: movl %eax, %edx 135; X86-NEXT: shll %cl, %edx 136; X86-NEXT: movswl %dx, %esi 137; X86-NEXT: # kill: def $cl killed $cl killed $ecx 138; X86-NEXT: sarl %cl, %esi 139; X86-NEXT: xorl %ecx, %ecx 140; X86-NEXT: testw %ax, %ax 141; X86-NEXT: sets %cl 142; X86-NEXT: addl $32767, %ecx # imm = 0x7FFF 143; X86-NEXT: cmpw %si, %ax 144; X86-NEXT: cmovel %edx, %ecx 145; X86-NEXT: movswl %cx, %eax 146; X86-NEXT: shrl %eax 147; X86-NEXT: # kill: def $ax killed $ax killed $eax 148; X86-NEXT: popl %esi 149; X86-NEXT: retl 150 %y2 = sext i8 %y to i15 151 %y3 = shl i15 %y2, 7 152 %tmp = call i15 @llvm.sshl.sat.i15(i15 %x, i15 %y3) 153 %tmp2 = sext i15 %tmp to i16 154 ret i16 %tmp2 155} 156 157define i4 @func4(i4 %x, i4 %y) nounwind { 158; X64-LABEL: func4: 159; X64: # %bb.0: 160; X64-NEXT: movl %esi, %ecx 161; X64-NEXT: andb $15, %cl 162; X64-NEXT: shlb $4, %dil 163; X64-NEXT: movl %edi, %eax 164; X64-NEXT: shlb %cl, %al 165; X64-NEXT: movzbl %al, %edx 166; X64-NEXT: movl %edx, %esi 167; X64-NEXT: # kill: def $cl killed $cl killed $ecx 168; X64-NEXT: sarb %cl, %sil 169; X64-NEXT: xorl %eax, %eax 170; X64-NEXT: testb %dil, %dil 171; X64-NEXT: sets %al 172; X64-NEXT: addl $127, %eax 173; X64-NEXT: cmpb %sil, %dil 174; X64-NEXT: cmovel %edx, %eax 175; X64-NEXT: sarb $4, %al 176; X64-NEXT: # kill: def $al killed $al killed $eax 177; X64-NEXT: retq 178; 179; X86-LABEL: func4: 180; X86: # %bb.0: 181; X86-NEXT: pushl %esi 182; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 183; X86-NEXT: andb $15, %cl 184; X86-NEXT: movzbl {{[0-9]+}}(%esp), %edx 185; X86-NEXT: shlb $4, %dl 186; X86-NEXT: movb %dl, %ch 187; X86-NEXT: shlb %cl, %ch 188; X86-NEXT: movzbl %ch, %esi 189; X86-NEXT: sarb %cl, %ch 190; X86-NEXT: xorl %eax, %eax 191; X86-NEXT: testb %dl, %dl 192; X86-NEXT: sets %al 193; X86-NEXT: addl $127, %eax 194; X86-NEXT: cmpb %ch, %dl 195; X86-NEXT: cmovel %esi, %eax 196; X86-NEXT: sarb $4, %al 197; X86-NEXT: # kill: def $al killed $al killed $eax 198; X86-NEXT: popl %esi 199; X86-NEXT: retl 200 %tmp = call i4 @llvm.sshl.sat.i4(i4 %x, i4 %y) 201 ret i4 %tmp 202} 203 204define i64 @func5(i64 %x, i64 %y) nounwind { 205; X64-LABEL: func5: 206; X64: # %bb.0: 207; X64-NEXT: movq %rsi, %rcx 208; X64-NEXT: xorl %eax, %eax 209; X64-NEXT: testq %rdi, %rdi 210; X64-NEXT: sets %al 211; X64-NEXT: movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF 212; X64-NEXT: addq %rax, %rdx 213; X64-NEXT: movq %rdi, %rax 214; X64-NEXT: shlq %cl, %rax 215; X64-NEXT: movq %rax, %rsi 216; X64-NEXT: # kill: def $cl killed $cl killed $rcx 217; X64-NEXT: sarq %cl, %rsi 218; X64-NEXT: cmpq %rsi, %rdi 219; X64-NEXT: cmovneq %rdx, %rax 220; X64-NEXT: retq 221; 222; X86-LABEL: func5: 223; X86: # %bb.0: 224; X86-NEXT: pushl %ebp 225; X86-NEXT: pushl %ebx 226; X86-NEXT: pushl %edi 227; X86-NEXT: pushl %esi 228; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 229; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 230; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 231; X86-NEXT: movl %edx, %ebx 232; X86-NEXT: shll %cl, %ebx 233; X86-NEXT: movl %eax, %esi 234; X86-NEXT: shldl %cl, %edx, %esi 235; X86-NEXT: xorl %edi, %edi 236; X86-NEXT: testb $32, %cl 237; X86-NEXT: cmovnel %ebx, %esi 238; X86-NEXT: cmovel %ebx, %edi 239; X86-NEXT: movl %esi, %edx 240; X86-NEXT: sarl %cl, %edx 241; X86-NEXT: movl %esi, %ebx 242; X86-NEXT: sarl $31, %ebx 243; X86-NEXT: testb $32, %cl 244; X86-NEXT: cmovel %edx, %ebx 245; X86-NEXT: movl %edi, %ebp 246; X86-NEXT: shrdl %cl, %esi, %ebp 247; X86-NEXT: testb $32, %cl 248; X86-NEXT: cmovnel %edx, %ebp 249; X86-NEXT: xorl %eax, %ebx 250; X86-NEXT: xorl {{[0-9]+}}(%esp), %ebp 251; X86-NEXT: sarl $31, %eax 252; X86-NEXT: movl %eax, %edx 253; X86-NEXT: xorl $2147483647, %edx # imm = 0x7FFFFFFF 254; X86-NEXT: orl %ebx, %ebp 255; X86-NEXT: notl %eax 256; X86-NEXT: cmovel %edi, %eax 257; X86-NEXT: cmovel %esi, %edx 258; X86-NEXT: popl %esi 259; X86-NEXT: popl %edi 260; X86-NEXT: popl %ebx 261; X86-NEXT: popl %ebp 262; X86-NEXT: retl 263 %tmp = call i64 @llvm.sshl.sat.i64(i64 %x, i64 %y) 264 ret i64 %tmp 265} 266 267define i18 @func6(i16 %x, i16 %y) nounwind { 268; X64-LABEL: func6: 269; X64: # %bb.0: 270; X64-NEXT: movl %esi, %ecx 271; X64-NEXT: movswl %di, %edx 272; X64-NEXT: shll $14, %edx 273; X64-NEXT: movl %edx, %esi 274; X64-NEXT: shll %cl, %esi 275; X64-NEXT: movl %esi, %edi 276; X64-NEXT: # kill: def $cl killed $cl killed $ecx 277; X64-NEXT: sarl %cl, %edi 278; X64-NEXT: xorl %eax, %eax 279; X64-NEXT: testl %edx, %edx 280; X64-NEXT: sets %al 281; X64-NEXT: addl $2147483647, %eax # imm = 0x7FFFFFFF 282; X64-NEXT: cmpl %edi, %edx 283; X64-NEXT: cmovel %esi, %eax 284; X64-NEXT: sarl $14, %eax 285; X64-NEXT: retq 286; 287; X86-LABEL: func6: 288; X86: # %bb.0: 289; X86-NEXT: pushl %edi 290; X86-NEXT: pushl %esi 291; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 292; X86-NEXT: movswl {{[0-9]+}}(%esp), %edx 293; X86-NEXT: shll $14, %edx 294; X86-NEXT: movl %edx, %esi 295; X86-NEXT: shll %cl, %esi 296; X86-NEXT: movl %esi, %edi 297; X86-NEXT: sarl %cl, %edi 298; X86-NEXT: xorl %eax, %eax 299; X86-NEXT: testl %edx, %edx 300; X86-NEXT: sets %al 301; X86-NEXT: addl $2147483647, %eax # imm = 0x7FFFFFFF 302; X86-NEXT: cmpl %edi, %edx 303; X86-NEXT: cmovel %esi, %eax 304; X86-NEXT: sarl $14, %eax 305; X86-NEXT: popl %esi 306; X86-NEXT: popl %edi 307; X86-NEXT: retl 308 %x2 = sext i16 %x to i18 309 %y2 = sext i16 %y to i18 310 %tmp = call i18 @llvm.sshl.sat.i18(i18 %x2, i18 %y2) 311 ret i18 %tmp 312} 313 314define i32 @func7(i32 %x, i32 %y) nounwind { 315; X64-LABEL: func7: 316; X64: # %bb.0: 317; X64-NEXT: movl %esi, %ecx 318; X64-NEXT: movl %edi, %edx 319; X64-NEXT: shll %cl, %edx 320; X64-NEXT: movl %edx, %esi 321; X64-NEXT: # kill: def $cl killed $cl killed $ecx 322; X64-NEXT: sarl %cl, %esi 323; X64-NEXT: xorl %eax, %eax 324; X64-NEXT: testl %edi, %edi 325; X64-NEXT: sets %al 326; X64-NEXT: addl $2147483647, %eax # imm = 0x7FFFFFFF 327; X64-NEXT: cmpl %esi, %edi 328; X64-NEXT: cmovel %edx, %eax 329; X64-NEXT: retq 330; 331; X86-LABEL: func7: 332; X86: # %bb.0: 333; X86-NEXT: pushl %edi 334; X86-NEXT: pushl %esi 335; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 336; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 337; X86-NEXT: movl %edx, %esi 338; X86-NEXT: shll %cl, %esi 339; X86-NEXT: movl %esi, %edi 340; X86-NEXT: sarl %cl, %edi 341; X86-NEXT: xorl %eax, %eax 342; X86-NEXT: testl %edx, %edx 343; X86-NEXT: sets %al 344; X86-NEXT: addl $2147483647, %eax # imm = 0x7FFFFFFF 345; X86-NEXT: cmpl %edi, %edx 346; X86-NEXT: cmovel %esi, %eax 347; X86-NEXT: popl %esi 348; X86-NEXT: popl %edi 349; X86-NEXT: retl 350 %tmp = call i32 @llvm.sshl.sat.i32(i32 %x, i32 %y) 351 ret i32 %tmp 352} 353 354define i8 @func8(i8 %x, i8 %y) nounwind { 355; X64-LABEL: func8: 356; X64: # %bb.0: 357; X64-NEXT: movl %esi, %ecx 358; X64-NEXT: movl %edi, %eax 359; X64-NEXT: shlb %cl, %al 360; X64-NEXT: movzbl %al, %edx 361; X64-NEXT: movl %edx, %esi 362; X64-NEXT: # kill: def $cl killed $cl killed $ecx 363; X64-NEXT: sarb %cl, %sil 364; X64-NEXT: xorl %eax, %eax 365; X64-NEXT: testb %dil, %dil 366; X64-NEXT: sets %al 367; X64-NEXT: addl $127, %eax 368; X64-NEXT: cmpb %sil, %dil 369; X64-NEXT: cmovel %edx, %eax 370; X64-NEXT: # kill: def $al killed $al killed $eax 371; X64-NEXT: retq 372; 373; X86-LABEL: func8: 374; X86: # %bb.0: 375; X86-NEXT: pushl %esi 376; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 377; X86-NEXT: movzbl {{[0-9]+}}(%esp), %edx 378; X86-NEXT: movb %dl, %ch 379; X86-NEXT: shlb %cl, %ch 380; X86-NEXT: movzbl %ch, %esi 381; X86-NEXT: sarb %cl, %ch 382; X86-NEXT: xorl %eax, %eax 383; X86-NEXT: testb %dl, %dl 384; X86-NEXT: sets %al 385; X86-NEXT: addl $127, %eax 386; X86-NEXT: cmpb %ch, %dl 387; X86-NEXT: cmovel %esi, %eax 388; X86-NEXT: # kill: def $al killed $al killed $eax 389; X86-NEXT: popl %esi 390; X86-NEXT: retl 391 %tmp = call i8 @llvm.sshl.sat.i8(i8 %x, i8 %y) 392 ret i8 %tmp 393} 394