1; We run the tests with both the default optimization level and O0, to make sure 2; we don't have any ABI differences between them. In principle, the ABI checks 3; should be the same for both optimization levels (there could be exceptions 4; from this when a div and a mod with the same operands are not coallesced into 5; the same divmod, but luckily this doesn't occur in practice even at O0). 6; Sometimes the checks that the correct registers are used after the libcalls 7; are different between optimization levels, so we have to separate them. 8; RUN: llc -mtriple armv7-none-eabi %s -o - | FileCheck %s --check-prefix=EABI 9; RUN: llc -mtriple armv7-none-eabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI 10; RUN: llc -mtriple armv7-none-eabihf %s -o - | FileCheck %s --check-prefix=EABI 11; RUN: llc -mtriple armv7-none-eabihf %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI 12; All "eabi" (Bare, GNU and Android) must lower SREM/UREM to __aeabi_{u,i}divmod 13; RUN: llc -mtriple armv7-linux-androideabi %s -o - | FileCheck %s --check-prefix=EABI 14; RUN: llc -mtriple armv7-linux-androideabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI 15; RUN: llc -mtriple armv7-linux-gnueabi %s -o - | FileCheck %s --check-prefix=EABI 16; RUN: llc -mtriple armv7-linux-gnueabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI 17; RUN: llc -mtriple armv7-linux-musleabi %s -o - | FileCheck %s --check-prefix=EABI 18; RUN: llc -mtriple armv7-linux-musleabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI 19; RUN: llc -mtriple armv7-apple-darwin %s -o - | FileCheck %s --check-prefixes=DARWIN 20; RUN: llc -mtriple armv7-apple-darwin %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=DARWIN-O0 21; RUN: llc -mtriple thumbv7-windows %s -o - | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-DEFAULT 22; RUN: llc -mtriple thumbv7-windows %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-O0 23 24define signext i16 @f16(i16 signext %a, i16 signext %b) { 25; EABI-LABEL: f16: 26; DARWIN-LABEL: f16: 27; DARWIN-O0-LABEL: f16: 28; WINDOWS-LABEL: f16: 29entry: 30 %conv = sext i16 %a to i32 31 %conv1 = sext i16 %b to i32 32 %div = sdiv i32 %conv, %conv1 33 %rem = srem i32 %conv, %conv1 34; EABI: __aeabi_idivmod 35; EABI: mov [[div:r[0-9]+]], r0 36; EABI: mov [[rem:r[0-9]+]], r1 37; DARWIN: __divmodsi4 38; DARWIN-O0: __divsi3 39; DARWIN-O0: __modsi3 40; WINDOWS: __rt_sdiv 41; WINDOWS: __rt_sdiv 42; WINDOWS-DEFAULT: add [[sum:r[0-9]+]], r1 43; WINDOWS-O0: mov [[rem:r[0-9]+]], r1 44 %rem8 = srem i32 %conv1, %conv 45; EABI: __aeabi_idivmod 46; DARWIN: __modsi3 47; DARWIN-O0: __modsi3 48; WINDOWS: __rt_sdiv 49 %add = add nsw i32 %rem, %div 50 %add13 = add nsw i32 %add, %rem8 51 %conv14 = trunc i32 %add13 to i16 52; EABI: add r0{{.*}}r1 53; EABI: sxth r0, r0 54; WINDOWS-DEFAULT: adds [[sum1:r[0-9]+]], [[sum]], r1 55; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], 56; WINDOWS-O0: add [[sum1:r[0-9]+]], r1 57; WINDOWS: sxth [[res:r[0-9]+]], [[sum1]] 58 ret i16 %conv14 59} 60 61define i32 @f32(i32 %a, i32 %b) { 62; EABI-LABEL: f32: 63; DARWIN-LABEL: f32: 64; DARWIN-O0-LABEL: f32: 65; WINDOWS-LABEL: f32: 66entry: 67 %div = sdiv i32 %a, %b 68 %rem = srem i32 %a, %b 69; EABI: __aeabi_idivmod 70; EABI: mov [[div:r[0-9]+]], r0 71; EABI: mov [[rem:r[0-9]+]], r1 72; DARWIN: ___divmodsi4 73; DARWIN-O0: __divsi3 74; DARWIN-O0: __modsi3 75; WINDOWS: __rt_sdiv 76; WINDOWS: mov [[div:r[0-9]+]], r0 77; WINDOWS: __rt_sdiv 78; WINDOWS-DEFAULT: add [[div]], r1 79 %rem1 = srem i32 %b, %a 80; EABI: __aeabi_idivmod 81; DARWIN: __modsi3 82; DARWIN-O0: __modsi3 83; WINDOWS: __rt_sdiv 84 %add = add nsw i32 %rem, %div 85 %add2 = add nsw i32 %add, %rem1 86; EABI: add r0{{.*}}r1 87; WINDOWS-DEFAULT: adds r0, [[div]], r1 88; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]] 89; WINDOWS-O0: add [[sum]], r1 90 ret i32 %add2 91} 92 93define i32 @uf(i32 %a, i32 %b) { 94; EABI-LABEL: uf: 95; DARWIN-LABEL: uf: 96; DARWIN-O0-LABEL: uf: 97; WINDOWS-LABEL: uf: 98entry: 99 %div = udiv i32 %a, %b 100 %rem = urem i32 %a, %b 101; EABI: __aeabi_uidivmod 102; DARWIN: __udivmodsi4 103; DARWIN-O0: __udivsi3 104; DARWIN-O0: __umodsi3 105; WINDOWS: __rt_udiv 106; WINDOWS: mov [[div:r[0-9]+]], r0 107; WINDOWS: __rt_udiv 108; WINDOWS-DEFAULT: add [[div]], r1 109 %rem1 = urem i32 %b, %a 110; EABI: __aeabi_uidivmod 111; DARWIN: __umodsi3 112; DARWIN-O0: __umodsi3 113; WINDOWS: __rt_udiv 114 %add = add nuw i32 %rem, %div 115 %add2 = add nuw i32 %add, %rem1 116; EABI: add r0{{.*}}r1 117; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[div]], r1 118; WINDOWS-O0: adds [[sum:r[0-9]+]], 119; WINDOWS-O0: add [[sum]], r1 120 ret i32 %add2 121} 122 123define i64 @longf(i64 %a, i64 %b) { 124; EABI-LABEL: longf: 125; DARWIN-LABEL: longf: 126; DARWIN-O0-LABEL: longf: 127; WINDOWS-LABEL: longf: 128entry: 129 %div = sdiv i64 %a, %b 130 %rem = srem i64 %a, %b 131; EABI: __aeabi_ldivmod 132; EABI-NEXT: adds r0 133; EABI-NEXT: adc r1 134; EABI-NOT: __aeabi_ldivmod 135; DARWIN: ___divdi3 136; DARWIN: mov [[div1:r[0-9]+]], r0 137; DARWIN: mov [[div2:r[0-9]+]], r1 138; DARWIN: __moddi3 139; DARWIN-O0: __divdi3 140; DARWIN-O0: __moddi3 141; WINDOWS: __rt_sdiv64 142 %add = add nsw i64 %rem, %div 143; DARWIN: adds r0{{.*}}[[div1]] 144; DARWIN: adc r1{{.*}}[[div2]] 145; WINDOWS: adds r0, r0, r2 146; WINDOWS: adcs r1, r3 147 ret i64 %add 148} 149 150define i16 @shortf(i16 %a, i16 %b) { 151; EABI-LABEL: shortf: 152; DARWIN-LABEL: shortf: 153; DARWIN-O0-LABEL: shortf: 154; WINDOWS-LABEL: shortf: 155entry: 156 %div = sdiv i16 %a, %b 157 %rem = srem i16 %a, %b 158; EABI: __aeabi_idivmod 159; DARWIN: ___divmodsi4 160; DARWIN-O0: __divmodsi4 161; WINDOWS: __rt_sdiv 162; WINDOWS: mov [[div:r[0-9]+]], r0 163; WINDOWS: __rt_sdiv 164 %add = add nsw i16 %rem, %div 165; EABI: add r0, r1 166; WINDOWS: adds r0, r1, [[div]] 167 ret i16 %add 168} 169 170define i32 @g1(i32 %a, i32 %b) { 171; EABI-LABEL: g1: 172; DARWIN-LABEL: g1: 173; DARWIN-O0-LABEL: g1: 174; WINDOWS-LABEL: g1: 175entry: 176 %div = sdiv i32 %a, %b 177 %rem = srem i32 %a, %b 178; EABI: __aeabi_idivmod 179; DARWIN: ___divmodsi4 180; DARWIN-O0: __divsi3 181; DARWIN-O0: __modsi3 182; WINDOWS: __rt_sdiv 183; WINDOWS: mov [[div:r[0-9]+]], r0 184; WINDOWS: __rt_sdiv 185 %add = add nsw i32 %rem, %div 186; EABI: add r0{{.*}}r1 187; WINDOWS: adds r0, r1, [[div]] 188 ret i32 %add 189} 190 191; On both Darwin and Gnu, this is just a call to __modsi3 192define i32 @g2(i32 %a, i32 %b) { 193; EABI-LABEL: g2: 194; DARWIN-LABEL: g2: 195; DARWIN-O0-LABEL: g2: 196; WINDOWS-LABEL: g2: 197entry: 198 %rem = srem i32 %a, %b 199; EABI: __aeabi_idivmod 200; DARWIN: __modsi3 201; DARWIN-O0: __modsi3 202; WINDOWS: __rt_sdiv 203 ret i32 %rem 204; EABI: mov r0, r1 205; WINDOWS: mov r0, r1 206} 207 208define i32 @g3(i32 %a, i32 %b) { 209; EABI-LABEL: g3: 210; DARWIN-LABEL: g3: 211; DARWIN-O0-LABEL: g3: 212; WINDOWS-LABEL: g3: 213entry: 214 %rem = srem i32 %a, %b 215; EABI: __aeabi_idivmod 216; EABI: mov [[mod:r[0-9]+]], r1 217; DARWIN: __modsi3 218; DARWIN: mov [[sum:r[0-9]+]], r0 219; DARWIN-O0: __modsi3 220; WINDOWS: __rt_sdiv 221; WINDOWS: mov [[rem:r[0-9]+]], r1 222 %rem1 = srem i32 %b, %rem 223; EABI: __aeabi_idivmod 224; DARWIN: __modsi3 225; DARWIN-O0: __modsi3 226; WINDOWS: __rt_sdiv 227 %add = add nsw i32 %rem1, %rem 228; EABI: add r0, r1, [[mod]] 229; DARWIN: add r0{{.*}}[[sum]] 230; WINDOWS: adds r0, r1, [[rem]] 231 ret i32 %add 232} 233 234define i32 @g4(i32 %a, i32 %b) { 235; EABI-LABEL: g4: 236; DARWIN-LABEL: g4: 237; DARWIN-O0-LABEL: g4: 238; WINDOWS-LABEL: g4: 239entry: 240 %div = sdiv i32 %a, %b 241; EABI: __aeabi_idiv{{$}} 242; EABI: mov [[div:r[0-9]+]], r0 243; DARWIN: ___divsi3 244; DARWIN: mov [[sum:r[0-9]+]], r0 245; DARWIN-O0: __divsi3 246; WINDOWS: __rt_sdiv 247; WINDOWS: mov [[div:r[0-9]+]], r0 248 %rem = srem i32 %b, %div 249; EABI: __aeabi_idivmod 250; DARWIN: __modsi3 251; DARWIN-O0: __modsi3 252; WINDOWS: __rt_sdiv 253 %add = add nsw i32 %rem, %div 254; EABI: add r0, r1, [[div]] 255; DARWIN: add r0{{.*}}[[sum]] 256; WINDOWS: adds r0, r1, [[div]] 257 ret i32 %add 258} 259