253 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s3 4;------------------------------------------------------------------------------;5; Odd divisors6;------------------------------------------------------------------------------;7 8define i32 @test_urem_odd(i32 %X) nounwind {9; CHECK-LABEL: test_urem_odd:10; CHECK: // %bb.0:11; CHECK-NEXT: mov w8, #52429 // =0xcccd12; CHECK-NEXT: mov w9, #858993459 // =0x3333333313; CHECK-NEXT: movk w8, #52428, lsl #1614; CHECK-NEXT: mul w8, w0, w815; CHECK-NEXT: cmp w8, w916; CHECK-NEXT: cset w0, ls17; CHECK-NEXT: ret18 %urem = urem i32 %X, 519 %cmp = icmp eq i32 %urem, 020 %ret = zext i1 %cmp to i3221 ret i32 %ret22}23 24define i32 @test_urem_odd_25(i32 %X) nounwind {25; CHECK-LABEL: test_urem_odd_25:26; CHECK: // %bb.0:27; CHECK-NEXT: mov w8, #23593 // =0x5c2928; CHECK-NEXT: mov w9, #28836 // =0x70a429; CHECK-NEXT: movk w8, #49807, lsl #1630; CHECK-NEXT: movk w9, #2621, lsl #1631; CHECK-NEXT: mul w8, w0, w832; CHECK-NEXT: cmp w8, w933; CHECK-NEXT: cset w0, lo34; CHECK-NEXT: ret35 %urem = urem i32 %X, 2536 %cmp = icmp eq i32 %urem, 037 %ret = zext i1 %cmp to i3238 ret i32 %ret39}40 41; This is like test_urem_odd, except the divisor has bit 30 set.42define i32 @test_urem_odd_bit30(i32 %X) nounwind {43; CHECK-LABEL: test_urem_odd_bit30:44; CHECK: // %bb.0:45; CHECK-NEXT: mov w8, #43691 // =0xaaab46; CHECK-NEXT: movk w8, #27306, lsl #1647; CHECK-NEXT: mul w8, w0, w848; CHECK-NEXT: cmp w8, #449; CHECK-NEXT: cset w0, lo50; CHECK-NEXT: ret51 %urem = urem i32 %X, 107374182752 %cmp = icmp eq i32 %urem, 053 %ret = zext i1 %cmp to i3254 ret i32 %ret55}56 57; This is like test_urem_odd, except the divisor has bit 31 set.58define i32 @test_urem_odd_bit31(i32 %X) nounwind {59; CHECK-LABEL: test_urem_odd_bit31:60; CHECK: // %bb.0:61; CHECK-NEXT: mov w8, #43691 // =0xaaab62; CHECK-NEXT: movk w8, #10922, lsl #1663; CHECK-NEXT: mul w8, w0, w864; CHECK-NEXT: cmp w8, #265; CHECK-NEXT: cset w0, lo66; CHECK-NEXT: ret67 %urem = urem i32 %X, 214748365168 %cmp = icmp eq i32 %urem, 069 %ret = zext i1 %cmp to i3270 ret i32 %ret71}72 73;------------------------------------------------------------------------------;74; Even divisors75;------------------------------------------------------------------------------;76 77define i16 @test_urem_even(i16 %X) nounwind {78; CHECK-LABEL: test_urem_even:79; CHECK: // %bb.0:80; CHECK-NEXT: mov w8, #28087 // =0x6db781; CHECK-NEXT: mul w8, w0, w882; CHECK-NEXT: and w9, w8, #0xfffc83; CHECK-NEXT: lsr w9, w9, #184; CHECK-NEXT: orr w8, w9, w8, lsl #1585; CHECK-NEXT: ubfx w8, w8, #1, #1586; CHECK-NEXT: cmp w8, #234087; CHECK-NEXT: cset w0, hi88; CHECK-NEXT: ret89 %urem = urem i16 %X, 1490 %cmp = icmp ne i16 %urem, 091 %ret = zext i1 %cmp to i1692 ret i16 %ret93}94 95define i32 @test_urem_even_100(i32 %X) nounwind {96; CHECK-LABEL: test_urem_even_100:97; CHECK: // %bb.0:98; CHECK-NEXT: mov w8, #23593 // =0x5c2999; CHECK-NEXT: mov w9, #23593 // =0x5c29100; CHECK-NEXT: movk w8, #49807, lsl #16101; CHECK-NEXT: movk w9, #655, lsl #16102; CHECK-NEXT: mul w8, w0, w8103; CHECK-NEXT: ror w8, w8, #2104; CHECK-NEXT: cmp w8, w9105; CHECK-NEXT: cset w0, lo106; CHECK-NEXT: ret107 %urem = urem i32 %X, 100108 %cmp = icmp eq i32 %urem, 0109 %ret = zext i1 %cmp to i32110 ret i32 %ret111}112 113; This is like test_urem_even, except the divisor has bit 30 set.114define i32 @test_urem_even_bit30(i32 %X) nounwind {115; CHECK-LABEL: test_urem_even_bit30:116; CHECK: // %bb.0:117; CHECK-NEXT: mov w8, #20165 // =0x4ec5118; CHECK-NEXT: movk w8, #64748, lsl #16119; CHECK-NEXT: mul w8, w0, w8120; CHECK-NEXT: ror w8, w8, #3121; CHECK-NEXT: cmp w8, #4122; CHECK-NEXT: cset w0, lo123; CHECK-NEXT: ret124 %urem = urem i32 %X, 1073741928125 %cmp = icmp eq i32 %urem, 0126 %ret = zext i1 %cmp to i32127 ret i32 %ret128}129 130; This is like test_urem_odd, except the divisor has bit 31 set.131define i32 @test_urem_even_bit31(i32 %X) nounwind {132; CHECK-LABEL: test_urem_even_bit31:133; CHECK: // %bb.0:134; CHECK-NEXT: mov w8, #64251 // =0xfafb135; CHECK-NEXT: movk w8, #47866, lsl #16136; CHECK-NEXT: mul w8, w0, w8137; CHECK-NEXT: ror w8, w8, #1138; CHECK-NEXT: cmp w8, #2139; CHECK-NEXT: cset w0, lo140; CHECK-NEXT: ret141 %urem = urem i32 %X, 2147483750142 %cmp = icmp eq i32 %urem, 0143 %ret = zext i1 %cmp to i32144 ret i32 %ret145}146 147;------------------------------------------------------------------------------;148; Special case149;------------------------------------------------------------------------------;150 151; 'NE' predicate is fine too.152define i32 @test_urem_odd_setne(i32 %X) nounwind {153; CHECK-LABEL: test_urem_odd_setne:154; CHECK: // %bb.0:155; CHECK-NEXT: mov w8, #52429 // =0xcccd156; CHECK-NEXT: mov w9, #858993459 // =0x33333333157; CHECK-NEXT: movk w8, #52428, lsl #16158; CHECK-NEXT: mul w8, w0, w8159; CHECK-NEXT: cmp w8, w9160; CHECK-NEXT: cset w0, hi161; CHECK-NEXT: ret162 %urem = urem i32 %X, 5163 %cmp = icmp ne i32 %urem, 0164 %ret = zext i1 %cmp to i32165 ret i32 %ret166}167 168; The fold is only valid for positive divisors, negative-ones should be negated.169define i32 @test_urem_negative_odd(i32 %X) nounwind {170; CHECK-LABEL: test_urem_negative_odd:171; CHECK: // %bb.0:172; CHECK-NEXT: mov w8, #858993459 // =0x33333333173; CHECK-NEXT: mul w8, w0, w8174; CHECK-NEXT: cmp w8, #1175; CHECK-NEXT: cset w0, hi176; CHECK-NEXT: ret177 %urem = urem i32 %X, -5178 %cmp = icmp ne i32 %urem, 0179 %ret = zext i1 %cmp to i32180 ret i32 %ret181}182define i32 @test_urem_negative_even(i32 %X) nounwind {183; CHECK-LABEL: test_urem_negative_even:184; CHECK: // %bb.0:185; CHECK-NEXT: mov w8, #37449 // =0x9249186; CHECK-NEXT: movk w8, #51492, lsl #16187; CHECK-NEXT: mul w8, w0, w8188; CHECK-NEXT: ror w8, w8, #1189; CHECK-NEXT: cmp w8, #1190; CHECK-NEXT: cset w0, hi191; CHECK-NEXT: ret192 %urem = urem i32 %X, -14193 %cmp = icmp ne i32 %urem, 0194 %ret = zext i1 %cmp to i32195 ret i32 %ret196}197 198;------------------------------------------------------------------------------;199; Negative tests200;------------------------------------------------------------------------------;201 202; We can lower remainder of division by one much better elsewhere.203define i32 @test_urem_one(i32 %X) nounwind {204; CHECK-LABEL: test_urem_one:205; CHECK: // %bb.0:206; CHECK-NEXT: mov w0, #1 // =0x1207; CHECK-NEXT: ret208 %urem = urem i32 %X, 1209 %cmp = icmp eq i32 %urem, 0210 %ret = zext i1 %cmp to i32211 ret i32 %ret212}213 214; We can lower remainder of division by powers of two much better elsewhere.215define i32 @test_urem_pow2(i32 %X) nounwind {216; CHECK-LABEL: test_urem_pow2:217; CHECK: // %bb.0:218; CHECK-NEXT: tst w0, #0xf219; CHECK-NEXT: cset w0, eq220; CHECK-NEXT: ret221 %urem = urem i32 %X, 16222 %cmp = icmp eq i32 %urem, 0223 %ret = zext i1 %cmp to i32224 ret i32 %ret225}226 227; The fold is only valid for positive divisors, and we can't negate INT_MIN.228define i32 @test_urem_int_min(i32 %X) nounwind {229; CHECK-LABEL: test_urem_int_min:230; CHECK: // %bb.0:231; CHECK-NEXT: tst w0, #0x7fffffff232; CHECK-NEXT: cset w0, eq233; CHECK-NEXT: ret234 %urem = urem i32 %X, 2147483648235 %cmp = icmp eq i32 %urem, 0236 %ret = zext i1 %cmp to i32237 ret i32 %ret238}239 240; We can lower remainder of division by all-ones much better elsewhere.241define i32 @test_urem_allones(i32 %X) nounwind {242; CHECK-LABEL: test_urem_allones:243; CHECK: // %bb.0:244; CHECK-NEXT: neg w8, w0245; CHECK-NEXT: cmp w8, #2246; CHECK-NEXT: cset w0, lo247; CHECK-NEXT: ret248 %urem = urem i32 %X, 4294967295249 %cmp = icmp eq i32 %urem, 0250 %ret = zext i1 %cmp to i32251 ret i32 %ret252}253