331 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-- | FileCheck %s --check-prefixes=X86,X86-BASE3; RUN: llc < %s -mtriple=i686-- -mattr=movbe | FileCheck %s --check-prefixes=X86,X86-MOVBE4; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s --check-prefixes=X64,X64-BASE5; RUN: llc < %s -mtriple=x86_64-- -mattr=movbe | FileCheck %s --check-prefixes=X64,X64-MOVBE6 7define i16 @foo(i16 %x, i16 %y, i16 %z) nounwind {8; X86-LABEL: foo:9; X86: # %bb.0:10; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx11; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax12; X86-NEXT: rolw %cl, %ax13; X86-NEXT: retl14;15; X64-LABEL: foo:16; X64: # %bb.0:17; X64-NEXT: movl %edx, %ecx18; X64-NEXT: movl %edi, %eax19; X64-NEXT: # kill: def $cl killed $cl killed $ecx20; X64-NEXT: rolw %cl, %ax21; X64-NEXT: # kill: def $ax killed $ax killed $eax22; X64-NEXT: retq23 %t0 = shl i16 %x, %z24 %t1 = sub i16 16, %z25 %t2 = lshr i16 %x, %t126 %t3 = or i16 %t2, %t027 ret i16 %t328}29 30define i16 @bar(i16 %x, i16 %y, i16 %z) nounwind {31; X86-LABEL: bar:32; X86: # %bb.0:33; X86-NEXT: movzwl {{[0-9]+}}(%esp), %edx34; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax35; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx36; X86-NEXT: andb $15, %cl37; X86-NEXT: shldw %cl, %dx, %ax38; X86-NEXT: retl39;40; X64-LABEL: bar:41; X64: # %bb.0:42; X64-NEXT: movl %edx, %ecx43; X64-NEXT: movl %esi, %eax44; X64-NEXT: andb $15, %cl45; X64-NEXT: # kill: def $cl killed $cl killed $ecx46; X64-NEXT: shldw %cl, %di, %ax47; X64-NEXT: # kill: def $ax killed $ax killed $eax48; X64-NEXT: retq49 %t0 = shl i16 %y, %z50 %t1 = sub i16 16, %z51 %t2 = lshr i16 %x, %t152 %t3 = or i16 %t2, %t053 ret i16 %t354}55 56define i16 @un(i16 %x, i16 %y, i16 %z) nounwind {57; X86-LABEL: un:58; X86: # %bb.0:59; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx60; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax61; X86-NEXT: rorw %cl, %ax62; X86-NEXT: retl63;64; X64-LABEL: un:65; X64: # %bb.0:66; X64-NEXT: movl %edx, %ecx67; X64-NEXT: movl %edi, %eax68; X64-NEXT: # kill: def $cl killed $cl killed $ecx69; X64-NEXT: rorw %cl, %ax70; X64-NEXT: # kill: def $ax killed $ax killed $eax71; X64-NEXT: retq72 %t0 = lshr i16 %x, %z73 %t1 = sub i16 16, %z74 %t2 = shl i16 %x, %t175 %t3 = or i16 %t2, %t076 ret i16 %t377}78 79define i16 @bu(i16 %x, i16 %y, i16 %z) nounwind {80; X86-LABEL: bu:81; X86: # %bb.0:82; X86-NEXT: movzwl {{[0-9]+}}(%esp), %edx83; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax84; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx85; X86-NEXT: andb $15, %cl86; X86-NEXT: shrdw %cl, %dx, %ax87; X86-NEXT: retl88;89; X64-LABEL: bu:90; X64: # %bb.0:91; X64-NEXT: movl %edx, %ecx92; X64-NEXT: movl %esi, %eax93; X64-NEXT: andb $15, %cl94; X64-NEXT: # kill: def $cl killed $cl killed $ecx95; X64-NEXT: shrdw %cl, %di, %ax96; X64-NEXT: # kill: def $ax killed $ax killed $eax97; X64-NEXT: retq98 %t0 = lshr i16 %y, %z99 %t1 = sub i16 16, %z100 %t2 = shl i16 %x, %t1101 %t3 = or i16 %t2, %t0102 ret i16 %t3103}104 105define i16 @xfoo(i16 %x, i16 %y, i16 %z) nounwind {106; X86-LABEL: xfoo:107; X86: # %bb.0:108; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax109; X86-NEXT: rolw $5, %ax110; X86-NEXT: retl111;112; X64-LABEL: xfoo:113; X64: # %bb.0:114; X64-NEXT: movl %edi, %eax115; X64-NEXT: rolw $5, %ax116; X64-NEXT: # kill: def $ax killed $ax killed $eax117; X64-NEXT: retq118 %t0 = lshr i16 %x, 11119 %t1 = shl i16 %x, 5120 %t2 = or i16 %t0, %t1121 ret i16 %t2122}123 124define i16 @xbar(i16 %x, i16 %y, i16 %z) nounwind {125; X86-LABEL: xbar:126; X86: # %bb.0:127; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx128; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax129; X86-NEXT: shldw $5, %cx, %ax130; X86-NEXT: retl131;132; X64-LABEL: xbar:133; X64: # %bb.0:134; X64-NEXT: movl %esi, %eax135; X64-NEXT: shldw $5, %di, %ax136; X64-NEXT: # kill: def $ax killed $ax killed $eax137; X64-NEXT: retq138 %t0 = shl i16 %y, 5139 %t1 = lshr i16 %x, 11140 %t2 = or i16 %t0, %t1141 ret i16 %t2142}143 144define i16 @xun(i16 %x, i16 %y, i16 %z) nounwind {145; X86-LABEL: xun:146; X86: # %bb.0:147; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax148; X86-NEXT: rolw $11, %ax149; X86-NEXT: retl150;151; X64-LABEL: xun:152; X64: # %bb.0:153; X64-NEXT: movl %edi, %eax154; X64-NEXT: rolw $11, %ax155; X64-NEXT: # kill: def $ax killed $ax killed $eax156; X64-NEXT: retq157 %t0 = lshr i16 %x, 5158 %t1 = shl i16 %x, 11159 %t2 = or i16 %t0, %t1160 ret i16 %t2161}162 163define i16 @xbu(i16 %x, i16 %y, i16 %z) nounwind {164; X86-LABEL: xbu:165; X86: # %bb.0:166; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx167; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax168; X86-NEXT: shldw $11, %cx, %ax169; X86-NEXT: retl170;171; X64-LABEL: xbu:172; X64: # %bb.0:173; X64-NEXT: movl %edi, %eax174; X64-NEXT: shldw $11, %si, %ax175; X64-NEXT: # kill: def $ax killed $ax killed $eax176; X64-NEXT: retq177 %t0 = lshr i16 %y, 5178 %t1 = shl i16 %x, 11179 %t2 = or i16 %t0, %t1180 ret i16 %t2181}182 183define i32 @rot16_demandedbits(i32 %x, i32 %y) nounwind {184; X86-LABEL: rot16_demandedbits:185; X86: # %bb.0:186; X86-NEXT: movl {{[0-9]+}}(%esp), %eax187; X86-NEXT: movl %eax, %ecx188; X86-NEXT: shrl $11, %ecx189; X86-NEXT: shll $5, %eax190; X86-NEXT: orl %ecx, %eax191; X86-NEXT: movzwl %ax, %eax192; X86-NEXT: retl193;194; X64-LABEL: rot16_demandedbits:195; X64: # %bb.0:196; X64-NEXT: movl %edi, %eax197; X64-NEXT: shrl $11, %eax198; X64-NEXT: shll $5, %edi199; X64-NEXT: orl %eax, %edi200; X64-NEXT: movzwl %di, %eax201; X64-NEXT: retq202 %t0 = lshr i32 %x, 11203 %t1 = shl i32 %x, 5204 %t2 = or i32 %t0, %t1205 %t3 = and i32 %t2, 65535206 ret i32 %t3207}208 209define i16 @rot16_trunc(i32 %x, i32 %y) nounwind {210; X86-LABEL: rot16_trunc:211; X86: # %bb.0:212; X86-NEXT: movl {{[0-9]+}}(%esp), %eax213; X86-NEXT: movl %eax, %ecx214; X86-NEXT: shrl $11, %ecx215; X86-NEXT: shll $5, %eax216; X86-NEXT: orl %ecx, %eax217; X86-NEXT: # kill: def $ax killed $ax killed $eax218; X86-NEXT: retl219;220; X64-LABEL: rot16_trunc:221; X64: # %bb.0:222; X64-NEXT: movl %edi, %eax223; X64-NEXT: shrl $11, %eax224; X64-NEXT: shll $5, %edi225; X64-NEXT: orl %edi, %eax226; X64-NEXT: # kill: def $ax killed $ax killed $eax227; X64-NEXT: retq228 %t0 = lshr i32 %x, 11229 %t1 = shl i32 %x, 5230 %t2 = or i32 %t0, %t1231 %t3 = trunc i32 %t2 to i16232 ret i16 %t3233}234 235define i16 @rotate16(i16 %x) {236; X86-BASE-LABEL: rotate16:237; X86-BASE: # %bb.0:238; X86-BASE-NEXT: movzwl {{[0-9]+}}(%esp), %eax239; X86-BASE-NEXT: rolw $8, %ax240; X86-BASE-NEXT: retl241;242; X86-MOVBE-LABEL: rotate16:243; X86-MOVBE: # %bb.0:244; X86-MOVBE-NEXT: movbew {{[0-9]+}}(%esp), %ax245; X86-MOVBE-NEXT: retl246;247; X64-LABEL: rotate16:248; X64: # %bb.0:249; X64-NEXT: movl %edi, %eax250; X64-NEXT: rolw $8, %ax251; X64-NEXT: # kill: def $ax killed $ax killed $eax252; X64-NEXT: retq253 %r = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 8)254 ret i16 %r255}256 257; TODO: Should this always be rolw with memory operand?258 259define void @rotate16_in_place_memory(ptr %p) {260; X86-BASE-LABEL: rotate16_in_place_memory:261; X86-BASE: # %bb.0:262; X86-BASE-NEXT: movl {{[0-9]+}}(%esp), %eax263; X86-BASE-NEXT: rolw $8, (%eax)264; X86-BASE-NEXT: retl265;266; X86-MOVBE-LABEL: rotate16_in_place_memory:267; X86-MOVBE: # %bb.0:268; X86-MOVBE-NEXT: movl {{[0-9]+}}(%esp), %eax269; X86-MOVBE-NEXT: movzwl (%eax), %ecx270; X86-MOVBE-NEXT: movbew %cx, (%eax)271; X86-MOVBE-NEXT: retl272;273; X64-BASE-LABEL: rotate16_in_place_memory:274; X64-BASE: # %bb.0:275; X64-BASE-NEXT: rolw $8, (%rdi)276; X64-BASE-NEXT: retq277;278; X64-MOVBE-LABEL: rotate16_in_place_memory:279; X64-MOVBE: # %bb.0:280; X64-MOVBE-NEXT: movzwl (%rdi), %eax281; X64-MOVBE-NEXT: movbew %ax, (%rdi)282; X64-MOVBE-NEXT: retq283 %p1 = getelementptr i8, ptr %p, i64 1284 %i0 = load i8, ptr %p, align 1285 %i1 = load i8, ptr %p1, align 1286 store i8 %i1, ptr %p, align 1287 store i8 %i0, ptr %p1, align 1288 ret void289}290 291define void @rotate16_memory(ptr %p, ptr %q) {292; X86-BASE-LABEL: rotate16_memory:293; X86-BASE: # %bb.0:294; X86-BASE-NEXT: movl {{[0-9]+}}(%esp), %eax295; X86-BASE-NEXT: movl {{[0-9]+}}(%esp), %ecx296; X86-BASE-NEXT: movzwl (%ecx), %ecx297; X86-BASE-NEXT: rolw $8, %cx298; X86-BASE-NEXT: movw %cx, (%eax)299; X86-BASE-NEXT: retl300;301; X86-MOVBE-LABEL: rotate16_memory:302; X86-MOVBE: # %bb.0:303; X86-MOVBE-NEXT: movl {{[0-9]+}}(%esp), %eax304; X86-MOVBE-NEXT: movl {{[0-9]+}}(%esp), %ecx305; X86-MOVBE-NEXT: movzwl (%ecx), %ecx306; X86-MOVBE-NEXT: movbew %cx, (%eax)307; X86-MOVBE-NEXT: retl308;309; X64-BASE-LABEL: rotate16_memory:310; X64-BASE: # %bb.0:311; X64-BASE-NEXT: movzwl (%rdi), %eax312; X64-BASE-NEXT: rolw $8, %ax313; X64-BASE-NEXT: movw %ax, (%rsi)314; X64-BASE-NEXT: retq315;316; X64-MOVBE-LABEL: rotate16_memory:317; X64-MOVBE: # %bb.0:318; X64-MOVBE-NEXT: movzwl (%rdi), %eax319; X64-MOVBE-NEXT: movbew %ax, (%rsi)320; X64-MOVBE-NEXT: retq321 %p1 = getelementptr i8, ptr %p, i64 1322 %q1 = getelementptr i8, ptr %q, i64 1323 %i0 = load i8, ptr %p, align 1324 %i1 = load i8, ptr %p1, align 1325 store i8 %i1, ptr %q, align 1326 store i8 %i0, ptr %q1, align 1327 ret void328}329 330declare i16 @llvm.fshl.i16(i16, i16, i16)331