146 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s3 4; Check that under certain conditions we can factor out a rotate5; from the following idioms:6; (a*c0) >> s1 | (a*c1)7; (a/c0) << s1 | (a/c1)8; This targets cases where instcombine has folded a shl/srl/mul/udiv9; with one of the shifts from the rotate idiom10 11define i64 @ror_extract_shl(i64 %i) nounwind {12; CHECK-LABEL: ror_extract_shl:13; CHECK: // %bb.0:14; CHECK-NEXT: lsl x8, x0, #315; CHECK-NEXT: ror x0, x8, #5716; CHECK-NEXT: ret17 %lhs_mul = shl i64 %i, 318 %rhs_mul = shl i64 %i, 1019 %lhs_shift = lshr i64 %lhs_mul, 5720 %out = or i64 %lhs_shift, %rhs_mul21 ret i64 %out22}23 24define i32 @ror_extract_shrl(i32 %i) nounwind {25; CHECK-LABEL: ror_extract_shrl:26; CHECK: // %bb.0:27; CHECK-NEXT: lsr w8, w0, #328; CHECK-NEXT: ror w0, w8, #429; CHECK-NEXT: ret30 %lhs_div = lshr i32 %i, 731 %rhs_div = lshr i32 %i, 332 %rhs_shift = shl i32 %rhs_div, 2833 %out = or i32 %lhs_div, %rhs_shift34 ret i32 %out35}36 37define i32 @ror_extract_mul(i32 %i) nounwind {38; CHECK-LABEL: ror_extract_mul:39; CHECK: // %bb.0:40; CHECK-NEXT: add w8, w0, w0, lsl #341; CHECK-NEXT: ror w0, w8, #2542; CHECK-NEXT: ret43 %lhs_mul = mul i32 %i, 944 %rhs_mul = mul i32 %i, 115245 %lhs_shift = lshr i32 %lhs_mul, 2546 %out = or i32 %lhs_shift, %rhs_mul47 ret i32 %out48}49 50define i64 @ror_extract_udiv(i64 %i) nounwind {51; CHECK-LABEL: ror_extract_udiv:52; CHECK: // %bb.0:53; CHECK-NEXT: mov x8, #-6148914691236517206 // =0xaaaaaaaaaaaaaaaa54; CHECK-NEXT: movk x8, #4369155; CHECK-NEXT: umulh x8, x0, x856; CHECK-NEXT: lsr x8, x8, #157; CHECK-NEXT: ror x0, x8, #458; CHECK-NEXT: ret59 %lhs_div = udiv i64 %i, 360 %rhs_div = udiv i64 %i, 4861 %lhs_shift = shl i64 %lhs_div, 6062 %out = or i64 %lhs_shift, %rhs_div63 ret i64 %out64}65 66define i64 @ror_extract_mul_with_mask(i64 %i) nounwind {67; CHECK-LABEL: ror_extract_mul_with_mask:68; CHECK: // %bb.0:69; CHECK-NEXT: add x8, x0, x0, lsl #370; CHECK-NEXT: ror x8, x8, #5771; CHECK-NEXT: and x0, x8, #0xff72; CHECK-NEXT: ret73 %lhs_mul = mul i64 %i, 115274 %rhs_mul = mul i64 %i, 975 %lhs_and = and i64 %lhs_mul, 16076 %rhs_shift = lshr i64 %rhs_mul, 5777 %out = or i64 %lhs_and, %rhs_shift78 ret i64 %out79}80 81; Result would undershift82define i64 @no_extract_shl(i64 %i) nounwind {83; CHECK-LABEL: no_extract_shl:84; CHECK: // %bb.0:85; CHECK-NEXT: lsl x8, x0, #1086; CHECK-NEXT: bfxil x8, x0, #52, #787; CHECK-NEXT: mov x0, x888; CHECK-NEXT: ret89 %lhs_mul = shl i64 %i, 590 %rhs_mul = shl i64 %i, 1091 %lhs_shift = lshr i64 %lhs_mul, 5792 %out = or i64 %lhs_shift, %rhs_mul93 ret i64 %out94}95 96; Result would overshift97define i32 @no_extract_shrl(i32 %i) nounwind {98; CHECK-LABEL: no_extract_shrl:99; CHECK: // %bb.0:100; CHECK-NEXT: lsr w8, w0, #3101; CHECK-NEXT: lsr w0, w0, #9102; CHECK-NEXT: bfi w0, w8, #28, #4103; CHECK-NEXT: ret104 %lhs_div = lshr i32 %i, 3105 %rhs_div = lshr i32 %i, 9106 %lhs_shift = shl i32 %lhs_div, 28107 %out = or i32 %lhs_shift, %rhs_div108 ret i32 %out109}110 111; Can factor 128 from 2304, but result is 18 instead of 9112define i64 @no_extract_mul(i64 %i) nounwind {113; CHECK-LABEL: no_extract_mul:114; CHECK: // %bb.0:115; CHECK-NEXT: add x8, x0, x0, lsl #3116; CHECK-NEXT: lsr x9, x8, #57117; CHECK-NEXT: orr x0, x9, x8, lsl #8118; CHECK-NEXT: ret119 %lhs_mul = mul i64 %i, 2304120 %rhs_mul = mul i64 %i, 9121 %rhs_shift = lshr i64 %rhs_mul, 57122 %out = or i64 %lhs_mul, %rhs_shift123 ret i64 %out124}125 126; Can't evenly factor 16 from 49127define i32 @no_extract_udiv(i32 %i) nounwind {128; CHECK-LABEL: no_extract_udiv:129; CHECK: // %bb.0:130; CHECK-NEXT: mov w8, #43691 // =0xaaab131; CHECK-NEXT: mov w9, #33437 // =0x829d132; CHECK-NEXT: movk w8, #43690, lsl #16133; CHECK-NEXT: movk w9, #21399, lsl #16134; CHECK-NEXT: umull x8, w0, w8135; CHECK-NEXT: umull x9, w0, w9136; CHECK-NEXT: lsr x8, x8, #33137; CHECK-NEXT: lsr x9, x9, #32138; CHECK-NEXT: extr w0, w8, w9, #4139; CHECK-NEXT: ret140 %lhs_div = udiv i32 %i, 3141 %rhs_div = udiv i32 %i, 49142 %lhs_shift = shl i32 %lhs_div, 28143 %out = or i32 %lhs_shift, %rhs_div144 ret i32 %out145}146