1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=powerpc64le-- | FileCheck %s 3 4declare i8 @llvm.fshl.i8(i8, i8, i8) 5declare i16 @llvm.fshl.i16(i16, i16, i16) 6declare i32 @llvm.fshl.i32(i32, i32, i32) 7declare i64 @llvm.fshl.i64(i64, i64, i64) 8declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>) 9 10declare i8 @llvm.fshr.i8(i8, i8, i8) 11declare i16 @llvm.fshr.i16(i16, i16, i16) 12declare i32 @llvm.fshr.i32(i32, i32, i32) 13declare i64 @llvm.fshr.i64(i64, i64, i64) 14declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>) 15 16; General case - all operands can be variables. 17 18define i32 @fshl_i32(i32 %x, i32 %y, i32 %z) { 19; CHECK-LABEL: fshl_i32: 20; CHECK: # %bb.0: 21; CHECK-NEXT: andi. 5, 5, 31 22; CHECK-NEXT: subfic 6, 5, 32 23; CHECK-NEXT: slw 5, 3, 5 24; CHECK-NEXT: srw 4, 4, 6 25; CHECK-NEXT: or 4, 5, 4 26; CHECK-NEXT: iseleq 3, 3, 4 27; CHECK-NEXT: blr 28 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %z) 29 ret i32 %f 30} 31 32define i64 @fshl_i64(i64 %x, i64 %y, i64 %z) { 33; CHECK-LABEL: fshl_i64: 34; CHECK: # %bb.0: 35; CHECK-NEXT: andi. 5, 5, 63 36; CHECK-NEXT: subfic 6, 5, 64 37; CHECK-NEXT: sld 5, 3, 5 38; CHECK-NEXT: srd 4, 4, 6 39; CHECK-NEXT: or 4, 5, 4 40; CHECK-NEXT: iseleq 3, 3, 4 41; CHECK-NEXT: blr 42 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %y, i64 %z) 43 ret i64 %f 44} 45 46; Verify that weird types are minimally supported. 47declare i37 @llvm.fshl.i37(i37, i37, i37) 48define i37 @fshl_i37(i37 %x, i37 %y, i37 %z) { 49; CHECK-LABEL: fshl_i37: 50; CHECK: # %bb.0: 51; CHECK-NEXT: lis 6, -8857 52; CHECK-NEXT: clrldi 5, 5, 27 53; CHECK-NEXT: ori 6, 6, 51366 54; CHECK-NEXT: clrldi 4, 4, 27 55; CHECK-NEXT: sldi 6, 6, 32 56; CHECK-NEXT: oris 6, 6, 3542 57; CHECK-NEXT: ori 6, 6, 31883 58; CHECK-NEXT: mulhdu 6, 5, 6 59; CHECK-NEXT: rldicl 6, 6, 59, 5 60; CHECK-NEXT: mulli 6, 6, 37 61; CHECK-NEXT: sub. 5, 5, 6 62; CHECK-NEXT: subfic 6, 5, 37 63; CHECK-NEXT: sld 5, 3, 5 64; CHECK-NEXT: srd 4, 4, 6 65; CHECK-NEXT: or 4, 5, 4 66; CHECK-NEXT: iseleq 3, 3, 4 67; CHECK-NEXT: blr 68 %f = call i37 @llvm.fshl.i37(i37 %x, i37 %y, i37 %z) 69 ret i37 %f 70} 71 72; extract(concat(0b1110000, 0b1111111) << 2) = 0b1000011 73 74declare i7 @llvm.fshl.i7(i7, i7, i7) 75define i7 @fshl_i7_const_fold() { 76; CHECK-LABEL: fshl_i7_const_fold: 77; CHECK: # %bb.0: 78; CHECK-NEXT: li 3, 67 79; CHECK-NEXT: blr 80 %f = call i7 @llvm.fshl.i7(i7 112, i7 127, i7 2) 81 ret i7 %f 82} 83 84; With constant shift amount, this is rotate + insert (missing extended mnemonics). 85 86define i32 @fshl_i32_const_shift(i32 %x, i32 %y) { 87; CHECK-LABEL: fshl_i32_const_shift: 88; CHECK: # %bb.0: 89; CHECK-NEXT: rotlwi 4, 4, 9 90; CHECK-NEXT: rlwimi 4, 3, 9, 0, 22 91; CHECK-NEXT: mr 3, 4 92; CHECK-NEXT: blr 93 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 9) 94 ret i32 %f 95} 96 97; Check modulo math on shift amount. 98 99define i32 @fshl_i32_const_overshift(i32 %x, i32 %y) { 100; CHECK-LABEL: fshl_i32_const_overshift: 101; CHECK: # %bb.0: 102; CHECK-NEXT: rotlwi 4, 4, 9 103; CHECK-NEXT: rlwimi 4, 3, 9, 0, 22 104; CHECK-NEXT: mr 3, 4 105; CHECK-NEXT: blr 106 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 41) 107 ret i32 %f 108} 109 110; 64-bit should also work. 111 112define i64 @fshl_i64_const_overshift(i64 %x, i64 %y) { 113; CHECK-LABEL: fshl_i64_const_overshift: 114; CHECK: # %bb.0: 115; CHECK-NEXT: rotldi 4, 4, 41 116; CHECK-NEXT: rldimi 4, 3, 41, 0 117; CHECK-NEXT: mr 3, 4 118; CHECK-NEXT: blr 119 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %y, i64 105) 120 ret i64 %f 121} 122 123; This should work without any node-specific logic. 124 125define i8 @fshl_i8_const_fold() { 126; CHECK-LABEL: fshl_i8_const_fold: 127; CHECK: # %bb.0: 128; CHECK-NEXT: li 3, 128 129; CHECK-NEXT: blr 130 %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 7) 131 ret i8 %f 132} 133 134; Repeat everything for funnel shift right. 135 136; General case - all operands can be variables. 137 138define i32 @fshr_i32(i32 %x, i32 %y, i32 %z) { 139; CHECK-LABEL: fshr_i32: 140; CHECK: # %bb.0: 141; CHECK-NEXT: andi. 5, 5, 31 142; CHECK-NEXT: subfic 6, 5, 32 143; CHECK-NEXT: srw 5, 4, 5 144; CHECK-NEXT: slw 3, 3, 6 145; CHECK-NEXT: or 3, 3, 5 146; CHECK-NEXT: iseleq 3, 4, 3 147; CHECK-NEXT: blr 148 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %z) 149 ret i32 %f 150} 151 152define i64 @fshr_i64(i64 %x, i64 %y, i64 %z) { 153; CHECK-LABEL: fshr_i64: 154; CHECK: # %bb.0: 155; CHECK-NEXT: andi. 5, 5, 63 156; CHECK-NEXT: subfic 6, 5, 64 157; CHECK-NEXT: srd 5, 4, 5 158; CHECK-NEXT: sld 3, 3, 6 159; CHECK-NEXT: or 3, 3, 5 160; CHECK-NEXT: iseleq 3, 4, 3 161; CHECK-NEXT: blr 162 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %y, i64 %z) 163 ret i64 %f 164} 165 166; Verify that weird types are minimally supported. 167declare i37 @llvm.fshr.i37(i37, i37, i37) 168define i37 @fshr_i37(i37 %x, i37 %y, i37 %z) { 169; CHECK-LABEL: fshr_i37: 170; CHECK: # %bb.0: 171; CHECK-NEXT: lis 6, -8857 172; CHECK-NEXT: clrldi 5, 5, 27 173; CHECK-NEXT: ori 6, 6, 51366 174; CHECK-NEXT: sldi 6, 6, 32 175; CHECK-NEXT: oris 6, 6, 3542 176; CHECK-NEXT: ori 6, 6, 31883 177; CHECK-NEXT: mulhdu 6, 5, 6 178; CHECK-NEXT: rldicl 6, 6, 59, 5 179; CHECK-NEXT: mulli 6, 6, 37 180; CHECK-NEXT: sub. 5, 5, 6 181; CHECK-NEXT: clrldi 6, 4, 27 182; CHECK-NEXT: subfic 7, 5, 37 183; CHECK-NEXT: srd 5, 6, 5 184; CHECK-NEXT: sld 3, 3, 7 185; CHECK-NEXT: or 3, 3, 5 186; CHECK-NEXT: iseleq 3, 4, 3 187; CHECK-NEXT: blr 188 %f = call i37 @llvm.fshr.i37(i37 %x, i37 %y, i37 %z) 189 ret i37 %f 190} 191 192; extract(concat(0b1110000, 0b1111111) >> 2) = 0b0011111 193 194declare i7 @llvm.fshr.i7(i7, i7, i7) 195define i7 @fshr_i7_const_fold() { 196; CHECK-LABEL: fshr_i7_const_fold: 197; CHECK: # %bb.0: 198; CHECK-NEXT: li 3, 31 199; CHECK-NEXT: blr 200 %f = call i7 @llvm.fshr.i7(i7 112, i7 127, i7 2) 201 ret i7 %f 202} 203 204; With constant shift amount, this is rotate + insert (missing extended mnemonics). 205 206define i32 @fshr_i32_const_shift(i32 %x, i32 %y) { 207; CHECK-LABEL: fshr_i32_const_shift: 208; CHECK: # %bb.0: 209; CHECK-NEXT: rotlwi 4, 4, 23 210; CHECK-NEXT: rlwimi 4, 3, 23, 0, 8 211; CHECK-NEXT: mr 3, 4 212; CHECK-NEXT: blr 213 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 9) 214 ret i32 %f 215} 216 217; Check modulo math on shift amount. 41-32=9. 218 219define i32 @fshr_i32_const_overshift(i32 %x, i32 %y) { 220; CHECK-LABEL: fshr_i32_const_overshift: 221; CHECK: # %bb.0: 222; CHECK-NEXT: rotlwi 4, 4, 23 223; CHECK-NEXT: rlwimi 4, 3, 23, 0, 8 224; CHECK-NEXT: mr 3, 4 225; CHECK-NEXT: blr 226 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 41) 227 ret i32 %f 228} 229 230; 64-bit should also work. 105-64 = 41. 231 232define i64 @fshr_i64_const_overshift(i64 %x, i64 %y) { 233; CHECK-LABEL: fshr_i64_const_overshift: 234; CHECK: # %bb.0: 235; CHECK-NEXT: rotldi 4, 4, 23 236; CHECK-NEXT: rldimi 4, 3, 23, 0 237; CHECK-NEXT: mr 3, 4 238; CHECK-NEXT: blr 239 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %y, i64 105) 240 ret i64 %f 241} 242 243; This should work without any node-specific logic. 244 245define i8 @fshr_i8_const_fold() { 246; CHECK-LABEL: fshr_i8_const_fold: 247; CHECK: # %bb.0: 248; CHECK-NEXT: li 3, 254 249; CHECK-NEXT: blr 250 %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 7) 251 ret i8 %f 252} 253 254define i32 @fshl_i32_shift_by_bitwidth(i32 %x, i32 %y) { 255; CHECK-LABEL: fshl_i32_shift_by_bitwidth: 256; CHECK: # %bb.0: 257; CHECK-NEXT: blr 258 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 32) 259 ret i32 %f 260} 261 262define i32 @fshr_i32_shift_by_bitwidth(i32 %x, i32 %y) { 263; CHECK-LABEL: fshr_i32_shift_by_bitwidth: 264; CHECK: # %bb.0: 265; CHECK-NEXT: mr 3, 4 266; CHECK-NEXT: blr 267 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 32) 268 ret i32 %f 269} 270 271define <4 x i32> @fshl_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) { 272; CHECK-LABEL: fshl_v4i32_shift_by_bitwidth: 273; CHECK: # %bb.0: 274; CHECK-NEXT: blr 275 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>) 276 ret <4 x i32> %f 277} 278 279define <4 x i32> @fshr_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) { 280; CHECK-LABEL: fshr_v4i32_shift_by_bitwidth: 281; CHECK: # %bb.0: 282; CHECK-NEXT: vmr 2, 3 283; CHECK-NEXT: blr 284 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>) 285 ret <4 x i32> %f 286} 287 288