1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s 3 4; Shift i64 integers on 32-bit target 5 6define i64 @test1(i64 %X, i8 %C) nounwind { 7; CHECK-LABEL: test1: 8; CHECK: # BB#0: 9; CHECK-NEXT: pushl %esi 10; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 11; CHECK-NEXT: movl {{[0-9]+}}(%esp), %esi 12; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 13; CHECK-NEXT: movl %esi, %eax 14; CHECK-NEXT: shll %cl, %eax 15; CHECK-NEXT: shldl %cl, %esi, %edx 16; CHECK-NEXT: testb $32, %cl 17; CHECK-NEXT: je .LBB0_2 18; CHECK-NEXT: # BB#1: 19; CHECK-NEXT: movl %eax, %edx 20; CHECK-NEXT: xorl %eax, %eax 21; CHECK-NEXT: .LBB0_2: 22; CHECK-NEXT: popl %esi 23; CHECK-NEXT: retl 24 %shift.upgrd.1 = zext i8 %C to i64 ; <i64> [#uses=1] 25 %Y = shl i64 %X, %shift.upgrd.1 ; <i64> [#uses=1] 26 ret i64 %Y 27} 28 29define i64 @test2(i64 %X, i8 %C) nounwind { 30; CHECK-LABEL: test2: 31; CHECK: # BB#0: 32; CHECK-NEXT: pushl %esi 33; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 34; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 35; CHECK-NEXT: movl {{[0-9]+}}(%esp), %esi 36; CHECK-NEXT: movl %esi, %edx 37; CHECK-NEXT: sarl %cl, %edx 38; CHECK-NEXT: shrdl %cl, %esi, %eax 39; CHECK-NEXT: testb $32, %cl 40; CHECK-NEXT: je .LBB1_2 41; CHECK-NEXT: # BB#1: 42; CHECK-NEXT: sarl $31, %esi 43; CHECK-NEXT: movl %edx, %eax 44; CHECK-NEXT: movl %esi, %edx 45; CHECK-NEXT: .LBB1_2: 46; CHECK-NEXT: popl %esi 47; CHECK-NEXT: retl 48 %shift.upgrd.2 = zext i8 %C to i64 ; <i64> [#uses=1] 49 %Y = ashr i64 %X, %shift.upgrd.2 ; <i64> [#uses=1] 50 ret i64 %Y 51} 52 53define i64 @test3(i64 %X, i8 %C) nounwind { 54; CHECK-LABEL: test3: 55; CHECK: # BB#0: 56; CHECK-NEXT: pushl %esi 57; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 58; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 59; CHECK-NEXT: movl {{[0-9]+}}(%esp), %esi 60; CHECK-NEXT: movl %esi, %edx 61; CHECK-NEXT: shrl %cl, %edx 62; CHECK-NEXT: shrdl %cl, %esi, %eax 63; CHECK-NEXT: testb $32, %cl 64; CHECK-NEXT: je .LBB2_2 65; CHECK-NEXT: # BB#1: 66; CHECK-NEXT: movl %edx, %eax 67; CHECK-NEXT: xorl %edx, %edx 68; CHECK-NEXT: .LBB2_2: 69; CHECK-NEXT: popl %esi 70; CHECK-NEXT: retl 71 %shift.upgrd.3 = zext i8 %C to i64 ; <i64> [#uses=1] 72 %Y = lshr i64 %X, %shift.upgrd.3 ; <i64> [#uses=1] 73 ret i64 %Y 74} 75 76; Combine 2xi32/2xi16 shifts into SHLD 77 78define i32 @test4(i32 %A, i32 %B, i8 %C) nounwind { 79; CHECK-LABEL: test4: 80; CHECK: # BB#0: 81; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 82; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 83; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 84; CHECK-NEXT: shldl %cl, %edx, %eax 85; CHECK-NEXT: retl 86 %shift.upgrd.4 = zext i8 %C to i32 ; <i32> [#uses=1] 87 %X = shl i32 %A, %shift.upgrd.4 ; <i32> [#uses=1] 88 %Cv = sub i8 32, %C ; <i8> [#uses=1] 89 %shift.upgrd.5 = zext i8 %Cv to i32 ; <i32> [#uses=1] 90 %Y = lshr i32 %B, %shift.upgrd.5 ; <i32> [#uses=1] 91 %Z = or i32 %Y, %X ; <i32> [#uses=1] 92 ret i32 %Z 93} 94 95define i16 @test5(i16 %A, i16 %B, i8 %C) nounwind { 96; CHECK-LABEL: test5: 97; CHECK: # BB#0: 98; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 99; CHECK-NEXT: movzwl {{[0-9]+}}(%esp), %edx 100; CHECK-NEXT: movzwl {{[0-9]+}}(%esp), %eax 101; CHECK-NEXT: shldw %cl, %dx, %ax 102; CHECK-NEXT: retl 103 %shift.upgrd.6 = zext i8 %C to i16 ; <i16> [#uses=1] 104 %X = shl i16 %A, %shift.upgrd.6 ; <i16> [#uses=1] 105 %Cv = sub i8 16, %C ; <i8> [#uses=1] 106 %shift.upgrd.7 = zext i8 %Cv to i16 ; <i16> [#uses=1] 107 %Y = lshr i16 %B, %shift.upgrd.7 ; <i16> [#uses=1] 108 %Z = or i16 %Y, %X ; <i16> [#uses=1] 109 ret i16 %Z 110} 111 112; Combine 2xi32/2xi16 shifts into SHRD 113 114define i32 @test6(i32 %A, i32 %B, i8 %C) nounwind { 115; CHECK-LABEL: test6: 116; CHECK: # BB#0: 117; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 118; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 119; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 120; CHECK-NEXT: shrdl %cl, %edx, %eax 121; CHECK-NEXT: retl 122 %shift.upgrd.4 = zext i8 %C to i32 ; <i32> [#uses=1] 123 %X = lshr i32 %A, %shift.upgrd.4 ; <i32> [#uses=1] 124 %Cv = sub i8 32, %C ; <i8> [#uses=1] 125 %shift.upgrd.5 = zext i8 %Cv to i32 ; <i32> [#uses=1] 126 %Y = shl i32 %B, %shift.upgrd.5 ; <i32> [#uses=1] 127 %Z = or i32 %Y, %X ; <i32> [#uses=1] 128 ret i32 %Z 129} 130 131define i16 @test7(i16 %A, i16 %B, i8 %C) nounwind { 132; CHECK-LABEL: test7: 133; CHECK: # BB#0: 134; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 135; CHECK-NEXT: movzwl {{[0-9]+}}(%esp), %edx 136; CHECK-NEXT: movzwl {{[0-9]+}}(%esp), %eax 137; CHECK-NEXT: shrdw %cl, %dx, %ax 138; CHECK-NEXT: retl 139 %shift.upgrd.6 = zext i8 %C to i16 ; <i16> [#uses=1] 140 %X = lshr i16 %A, %shift.upgrd.6 ; <i16> [#uses=1] 141 %Cv = sub i8 16, %C ; <i8> [#uses=1] 142 %shift.upgrd.7 = zext i8 %Cv to i16 ; <i16> [#uses=1] 143 %Y = shl i16 %B, %shift.upgrd.7 ; <i16> [#uses=1] 144 %Z = or i16 %Y, %X ; <i16> [#uses=1] 145 ret i16 %Z 146} 147 148; Shift i64 integers on 32-bit target by shift value less then 32 (PR14593) 149 150define i64 @test8(i64 %val, i32 %bits) nounwind { 151; CHECK-LABEL: test8: 152; CHECK: # BB#0: 153; CHECK-NEXT: pushl %esi 154; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 155; CHECK-NEXT: movl {{[0-9]+}}(%esp), %esi 156; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 157; CHECK-NEXT: movl %esi, %eax 158; CHECK-NEXT: shll %cl, %eax 159; CHECK-NEXT: shldl %cl, %esi, %edx 160; CHECK-NEXT: popl %esi 161; CHECK-NEXT: retl 162 %and = and i32 %bits, 31 163 %sh_prom = zext i32 %and to i64 164 %shl = shl i64 %val, %sh_prom 165 ret i64 %shl 166} 167 168define i64 @test9(i64 %val, i32 %bits) nounwind { 169; CHECK-LABEL: test9: 170; CHECK: # BB#0: 171; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 172; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 173; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 174; CHECK-NEXT: shrdl %cl, %edx, %eax 175; CHECK-NEXT: sarl %cl, %edx 176; CHECK-NEXT: retl 177 %and = and i32 %bits, 31 178 %sh_prom = zext i32 %and to i64 179 %ashr = ashr i64 %val, %sh_prom 180 ret i64 %ashr 181} 182 183define i64 @test10(i64 %val, i32 %bits) nounwind { 184; CHECK-LABEL: test10: 185; CHECK: # BB#0: 186; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 187; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 188; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 189; CHECK-NEXT: shrdl %cl, %edx, %eax 190; CHECK-NEXT: shrl %cl, %edx 191; CHECK-NEXT: retl 192 %and = and i32 %bits, 31 193 %sh_prom = zext i32 %and to i64 194 %lshr = lshr i64 %val, %sh_prom 195 ret i64 %lshr 196} 197 198; SHLD/SHRD manual shifts 199 200define i32 @test11(i32 %hi, i32 %lo, i32 %bits) nounwind { 201; CHECK-LABEL: test11: 202; CHECK: # BB#0: 203; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 204; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 205; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 206; CHECK-NEXT: andl $31, %ecx 207; CHECK-NEXT: # kill: %CL<def> %CL<kill> %ECX<kill> 208; CHECK-NEXT: shldl %cl, %edx, %eax 209; CHECK-NEXT: retl 210 %and = and i32 %bits, 31 211 %and32 = sub i32 32, %and 212 %sh_lo = lshr i32 %lo, %and32 213 %sh_hi = shl i32 %hi, %and 214 %sh = or i32 %sh_lo, %sh_hi 215 ret i32 %sh 216} 217 218define i32 @test12(i32 %hi, i32 %lo, i32 %bits) nounwind { 219; CHECK-LABEL: test12: 220; CHECK: # BB#0: 221; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 222; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 223; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 224; CHECK-NEXT: andl $31, %ecx 225; CHECK-NEXT: # kill: %CL<def> %CL<kill> %ECX<kill> 226; CHECK-NEXT: shrdl %cl, %edx, %eax 227; CHECK-NEXT: retl 228 %and = and i32 %bits, 31 229 %and32 = sub i32 32, %and 230 %sh_lo = shl i32 %hi, %and32 231 %sh_hi = lshr i32 %lo, %and 232 %sh = or i32 %sh_lo, %sh_hi 233 ret i32 %sh 234} 235 236define i32 @test13(i32 %hi, i32 %lo, i32 %bits) nounwind { 237; CHECK-LABEL: test13: 238; CHECK: # BB#0: 239; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 240; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 241; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 242; CHECK-NEXT: shldl %cl, %edx, %eax 243; CHECK-NEXT: retl 244 %bits32 = sub i32 32, %bits 245 %sh_lo = lshr i32 %lo, %bits32 246 %sh_hi = shl i32 %hi, %bits 247 %sh = or i32 %sh_lo, %sh_hi 248 ret i32 %sh 249} 250 251define i32 @test14(i32 %hi, i32 %lo, i32 %bits) nounwind { 252; CHECK-LABEL: test14: 253; CHECK: # BB#0: 254; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 255; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 256; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 257; CHECK-NEXT: shrdl %cl, %edx, %eax 258; CHECK-NEXT: retl 259 %bits32 = sub i32 32, %bits 260 %sh_lo = shl i32 %hi, %bits32 261 %sh_hi = lshr i32 %lo, %bits 262 %sh = or i32 %sh_lo, %sh_hi 263 ret i32 %sh 264} 265 266define i32 @test15(i32 %hi, i32 %lo, i32 %bits) nounwind { 267; CHECK-LABEL: test15: 268; CHECK: # BB#0: 269; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 270; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 271; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 272; CHECK-NEXT: shldl %cl, %edx, %eax 273; CHECK-NEXT: retl 274 %bits32 = xor i32 %bits, 31 275 %lo2 = lshr i32 %lo, 1 276 %sh_lo = lshr i32 %lo2, %bits32 277 %sh_hi = shl i32 %hi, %bits 278 %sh = or i32 %sh_lo, %sh_hi 279 ret i32 %sh 280} 281 282define i32 @test16(i32 %hi, i32 %lo, i32 %bits) nounwind { 283; CHECK-LABEL: test16: 284; CHECK: # BB#0: 285; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 286; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 287; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 288; CHECK-NEXT: shrdl %cl, %edx, %eax 289; CHECK-NEXT: retl 290 %bits32 = xor i32 %bits, 31 291 %lo2 = shl i32 %lo, 1 292 %sh_lo = shl i32 %lo2, %bits32 293 %sh_hi = lshr i32 %hi, %bits 294 %sh = or i32 %sh_lo, %sh_hi 295 ret i32 %sh 296} 297 298define i32 @test17(i32 %hi, i32 %lo, i32 %bits) nounwind { 299; CHECK-LABEL: test17: 300; CHECK: # BB#0: 301; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl 302; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 303; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 304; CHECK-NEXT: shrdl %cl, %edx, %eax 305; CHECK-NEXT: retl 306 %bits32 = xor i32 %bits, 31 307 %lo2 = add i32 %lo, %lo 308 %sh_lo = shl i32 %lo2, %bits32 309 %sh_hi = lshr i32 %hi, %bits 310 %sh = or i32 %sh_lo, %sh_hi 311 ret i32 %sh 312} 313