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