1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-- -mcpu=corei7 | FileCheck %s --check-prefix=ALL --check-prefix=X64 3; RUN: llc < %s -mtriple=x86_64-- -mcpu=corei7-avx | FileCheck %s --check-prefix=ALL --check-prefix=SHLD 4; RUN: llc < %s -mtriple=x86_64-- -mcpu=core-avx2 | FileCheck %s --check-prefix=ALL --check-prefix=BMI2 5 6define i64 @foo(i64 %x, i64 %y, i64 %z) nounwind readnone { 7; ALL-LABEL: foo: 8; ALL: # %bb.0: # %entry 9; ALL-NEXT: movq %rdx, %rcx 10; ALL-NEXT: movq %rdi, %rax 11; ALL-NEXT: # kill: def $cl killed $cl killed $rcx 12; ALL-NEXT: rolq %cl, %rax 13; ALL-NEXT: retq 14entry: 15 %0 = shl i64 %x, %z 16 %1 = sub i64 64, %z 17 %2 = lshr i64 %x, %1 18 %3 = or i64 %2, %0 19 ret i64 %3 20} 21 22define i64 @bar(i64 %x, i64 %y, i64 %z) nounwind readnone { 23; ALL-LABEL: bar: 24; ALL: # %bb.0: # %entry 25; ALL-NEXT: movq %rdx, %rcx 26; ALL-NEXT: movq %rsi, %rax 27; ALL-NEXT: # kill: def $cl killed $cl killed $rcx 28; ALL-NEXT: shldq %cl, %rdi, %rax 29; ALL-NEXT: retq 30entry: 31 %0 = shl i64 %y, %z 32 %1 = sub i64 64, %z 33 %2 = lshr i64 %x, %1 34 %3 = or i64 %2, %0 35 ret i64 %3 36} 37 38define i64 @un(i64 %x, i64 %y, i64 %z) nounwind readnone { 39; ALL-LABEL: un: 40; ALL: # %bb.0: # %entry 41; ALL-NEXT: movq %rdx, %rcx 42; ALL-NEXT: movq %rdi, %rax 43; ALL-NEXT: # kill: def $cl killed $cl killed $rcx 44; ALL-NEXT: rorq %cl, %rax 45; ALL-NEXT: retq 46entry: 47 %0 = lshr i64 %x, %z 48 %1 = sub i64 64, %z 49 %2 = shl i64 %x, %1 50 %3 = or i64 %2, %0 51 ret i64 %3 52} 53 54define i64 @bu(i64 %x, i64 %y, i64 %z) nounwind readnone { 55; ALL-LABEL: bu: 56; ALL: # %bb.0: # %entry 57; ALL-NEXT: movq %rdx, %rcx 58; ALL-NEXT: movq %rsi, %rax 59; ALL-NEXT: # kill: def $cl killed $cl killed $rcx 60; ALL-NEXT: shrdq %cl, %rdi, %rax 61; ALL-NEXT: retq 62entry: 63 %0 = lshr i64 %y, %z 64 %1 = sub i64 64, %z 65 %2 = shl i64 %x, %1 66 %3 = or i64 %2, %0 67 ret i64 %3 68} 69 70define i64 @xfoo(i64 %x, i64 %y, i64 %z) nounwind readnone { 71; X64-LABEL: xfoo: 72; X64: # %bb.0: # %entry 73; X64-NEXT: movq %rdi, %rax 74; X64-NEXT: rolq $7, %rax 75; X64-NEXT: retq 76; 77; SHLD-LABEL: xfoo: 78; SHLD: # %bb.0: # %entry 79; SHLD-NEXT: movq %rdi, %rax 80; SHLD-NEXT: shldq $7, %rax, %rax 81; SHLD-NEXT: retq 82; 83; BMI2-LABEL: xfoo: 84; BMI2: # %bb.0: # %entry 85; BMI2-NEXT: rorxq $57, %rdi, %rax 86; BMI2-NEXT: retq 87entry: 88 %0 = lshr i64 %x, 57 89 %1 = shl i64 %x, 7 90 %2 = or i64 %0, %1 91 ret i64 %2 92} 93 94define i64 @xfoop(i64* %p) nounwind readnone { 95; X64-LABEL: xfoop: 96; X64: # %bb.0: # %entry 97; X64-NEXT: movq (%rdi), %rax 98; X64-NEXT: rolq $7, %rax 99; X64-NEXT: retq 100; 101; SHLD-LABEL: xfoop: 102; SHLD: # %bb.0: # %entry 103; SHLD-NEXT: movq (%rdi), %rax 104; SHLD-NEXT: shldq $7, %rax, %rax 105; SHLD-NEXT: retq 106; 107; BMI2-LABEL: xfoop: 108; BMI2: # %bb.0: # %entry 109; BMI2-NEXT: rorxq $57, (%rdi), %rax 110; BMI2-NEXT: retq 111entry: 112 %x = load i64, i64* %p 113 %a = lshr i64 %x, 57 114 %b = shl i64 %x, 7 115 %c = or i64 %a, %b 116 ret i64 %c 117} 118 119define i64 @xbar(i64 %x, i64 %y, i64 %z) nounwind readnone { 120; ALL-LABEL: xbar: 121; ALL: # %bb.0: # %entry 122; ALL-NEXT: movq %rdi, %rax 123; ALL-NEXT: shrdq $57, %rsi, %rax 124; ALL-NEXT: retq 125entry: 126 %0 = shl i64 %y, 7 127 %1 = lshr i64 %x, 57 128 %2 = or i64 %0, %1 129 ret i64 %2 130} 131 132define i64 @xun(i64 %x, i64 %y, i64 %z) nounwind readnone { 133; X64-LABEL: xun: 134; X64: # %bb.0: # %entry 135; X64-NEXT: movq %rdi, %rax 136; X64-NEXT: rolq $57, %rax 137; X64-NEXT: retq 138; 139; SHLD-LABEL: xun: 140; SHLD: # %bb.0: # %entry 141; SHLD-NEXT: movq %rdi, %rax 142; SHLD-NEXT: shldq $57, %rax, %rax 143; SHLD-NEXT: retq 144; 145; BMI2-LABEL: xun: 146; BMI2: # %bb.0: # %entry 147; BMI2-NEXT: rorxq $7, %rdi, %rax 148; BMI2-NEXT: retq 149entry: 150 %0 = lshr i64 %x, 7 151 %1 = shl i64 %x, 57 152 %2 = or i64 %0, %1 153 ret i64 %2 154} 155 156define i64 @xunp(i64* %p) nounwind readnone { 157; X64-LABEL: xunp: 158; X64: # %bb.0: # %entry 159; X64-NEXT: movq (%rdi), %rax 160; X64-NEXT: rolq $57, %rax 161; X64-NEXT: retq 162; 163; SHLD-LABEL: xunp: 164; SHLD: # %bb.0: # %entry 165; SHLD-NEXT: movq (%rdi), %rax 166; SHLD-NEXT: shldq $57, %rax, %rax 167; SHLD-NEXT: retq 168; 169; BMI2-LABEL: xunp: 170; BMI2: # %bb.0: # %entry 171; BMI2-NEXT: rorxq $7, (%rdi), %rax 172; BMI2-NEXT: retq 173entry: 174 %x = load i64, i64* %p 175 %a = lshr i64 %x, 7 176 %b = shl i64 %x, 57 177 %c = or i64 %a, %b 178 ret i64 %c 179} 180 181define i64 @xbu(i64 %x, i64 %y, i64 %z) nounwind readnone { 182; ALL-LABEL: xbu: 183; ALL: # %bb.0: # %entry 184; ALL-NEXT: movq %rdi, %rax 185; ALL-NEXT: shldq $57, %rsi, %rax 186; ALL-NEXT: retq 187entry: 188 %0 = lshr i64 %y, 7 189 %1 = shl i64 %x, 57 190 %2 = or i64 %0, %1 191 ret i64 %2 192} 193 194define i64 @fshl(i64 %x) nounwind { 195; X64-LABEL: fshl: 196; X64: # %bb.0: 197; X64-NEXT: movq %rdi, %rax 198; X64-NEXT: rolq $7, %rax 199; X64-NEXT: retq 200; 201; SHLD-LABEL: fshl: 202; SHLD: # %bb.0: 203; SHLD-NEXT: movq %rdi, %rax 204; SHLD-NEXT: shldq $7, %rax, %rax 205; SHLD-NEXT: retq 206; 207; BMI2-LABEL: fshl: 208; BMI2: # %bb.0: 209; BMI2-NEXT: rorxq $57, %rdi, %rax 210; BMI2-NEXT: retq 211 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 7) 212 ret i64 %f 213} 214declare i64 @llvm.fshl.i64(i64, i64, i64) 215 216define i64 @fshl1(i64 %x) nounwind { 217; X64-LABEL: fshl1: 218; X64: # %bb.0: 219; X64-NEXT: movq %rdi, %rax 220; X64-NEXT: rolq %rax 221; X64-NEXT: retq 222; 223; SHLD-LABEL: fshl1: 224; SHLD: # %bb.0: 225; SHLD-NEXT: movq %rdi, %rax 226; SHLD-NEXT: shldq $1, %rax, %rax 227; SHLD-NEXT: retq 228; 229; BMI2-LABEL: fshl1: 230; BMI2: # %bb.0: 231; BMI2-NEXT: rorxq $63, %rdi, %rax 232; BMI2-NEXT: retq 233 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 1) 234 ret i64 %f 235} 236 237define i64 @fshl63(i64 %x) nounwind { 238; X64-LABEL: fshl63: 239; X64: # %bb.0: 240; X64-NEXT: movq %rdi, %rax 241; X64-NEXT: rorq %rax 242; X64-NEXT: retq 243; 244; SHLD-LABEL: fshl63: 245; SHLD: # %bb.0: 246; SHLD-NEXT: movq %rdi, %rax 247; SHLD-NEXT: shldq $63, %rax, %rax 248; SHLD-NEXT: retq 249; 250; BMI2-LABEL: fshl63: 251; BMI2: # %bb.0: 252; BMI2-NEXT: rorxq $1, %rdi, %rax 253; BMI2-NEXT: retq 254 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 63) 255 ret i64 %f 256} 257 258define i64 @fshl_load(i64* %p) nounwind { 259; X64-LABEL: fshl_load: 260; X64: # %bb.0: 261; X64-NEXT: movq (%rdi), %rax 262; X64-NEXT: rolq $7, %rax 263; X64-NEXT: retq 264; 265; SHLD-LABEL: fshl_load: 266; SHLD: # %bb.0: 267; SHLD-NEXT: movq (%rdi), %rax 268; SHLD-NEXT: shldq $7, %rax, %rax 269; SHLD-NEXT: retq 270; 271; BMI2-LABEL: fshl_load: 272; BMI2: # %bb.0: 273; BMI2-NEXT: rorxq $57, (%rdi), %rax 274; BMI2-NEXT: retq 275 %x = load i64, i64* %p 276 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 7) 277 ret i64 %f 278} 279 280define i64 @fshr(i64 %x) nounwind { 281; X64-LABEL: fshr: 282; X64: # %bb.0: 283; X64-NEXT: movq %rdi, %rax 284; X64-NEXT: rorq $7, %rax 285; X64-NEXT: retq 286; 287; SHLD-LABEL: fshr: 288; SHLD: # %bb.0: 289; SHLD-NEXT: movq %rdi, %rax 290; SHLD-NEXT: shrdq $7, %rax, %rax 291; SHLD-NEXT: retq 292; 293; BMI2-LABEL: fshr: 294; BMI2: # %bb.0: 295; BMI2-NEXT: rorxq $7, %rdi, %rax 296; BMI2-NEXT: retq 297 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 7) 298 ret i64 %f 299} 300declare i64 @llvm.fshr.i64(i64, i64, i64) 301 302define i64 @fshr1(i64 %x) nounwind { 303; X64-LABEL: fshr1: 304; X64: # %bb.0: 305; X64-NEXT: movq %rdi, %rax 306; X64-NEXT: rorq %rax 307; X64-NEXT: retq 308; 309; SHLD-LABEL: fshr1: 310; SHLD: # %bb.0: 311; SHLD-NEXT: movq %rdi, %rax 312; SHLD-NEXT: shrdq $1, %rax, %rax 313; SHLD-NEXT: retq 314; 315; BMI2-LABEL: fshr1: 316; BMI2: # %bb.0: 317; BMI2-NEXT: rorxq $1, %rdi, %rax 318; BMI2-NEXT: retq 319 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 1) 320 ret i64 %f 321} 322 323define i64 @fshr63(i64 %x) nounwind { 324; X64-LABEL: fshr63: 325; X64: # %bb.0: 326; X64-NEXT: movq %rdi, %rax 327; X64-NEXT: rolq %rax 328; X64-NEXT: retq 329; 330; SHLD-LABEL: fshr63: 331; SHLD: # %bb.0: 332; SHLD-NEXT: movq %rdi, %rax 333; SHLD-NEXT: shrdq $63, %rax, %rax 334; SHLD-NEXT: retq 335; 336; BMI2-LABEL: fshr63: 337; BMI2: # %bb.0: 338; BMI2-NEXT: rorxq $63, %rdi, %rax 339; BMI2-NEXT: retq 340 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 63) 341 ret i64 %f 342} 343 344define i64 @fshr_load(i64* %p) nounwind { 345; X64-LABEL: fshr_load: 346; X64: # %bb.0: 347; X64-NEXT: movq (%rdi), %rax 348; X64-NEXT: rorq $7, %rax 349; X64-NEXT: retq 350; 351; SHLD-LABEL: fshr_load: 352; SHLD: # %bb.0: 353; SHLD-NEXT: movq (%rdi), %rax 354; SHLD-NEXT: shrdq $7, %rax, %rax 355; SHLD-NEXT: retq 356; 357; BMI2-LABEL: fshr_load: 358; BMI2: # %bb.0: 359; BMI2-NEXT: rorxq $7, (%rdi), %rax 360; BMI2-NEXT: retq 361 %x = load i64, i64* %p 362 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 7) 363 ret i64 %f 364} 365