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,DARWIN-DEFAULT 20; RUN: llc -mtriple armv7-apple-darwin %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=DARWIN,DARWIN-O0 21; FIXME: long-term, we will use "-apple-macho" and won't need this exception: 22; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - | FileCheck %s --check-prefixes=DARWIN,DARWIN-DEFAULT 23; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=DARWIN,DARWIN-O0 24; RUN: llc -mtriple thumbv7-windows %s -o - | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-DEFAULT 25; RUN: llc -mtriple thumbv7-windows %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-O0 26 27define signext i16 @f16(i16 signext %a, i16 signext %b) { 28; EABI-LABEL: f16: 29; DARWIN-LABEL: f16: 30; WINDOWS-LABEL: f16: 31entry: 32 %conv = sext i16 %a to i32 33 %conv1 = sext i16 %b to i32 34 %div = sdiv i32 %conv, %conv1 35 %rem = srem i32 %conv, %conv1 36; EABI: __aeabi_idivmod 37; EABI: mov [[div:r[0-9]+]], r0 38; EABI: mov [[rem:r[0-9]+]], r1 39; DARWIN: ___divsi3 40; DARWIN: mov [[div:r[0-9]+]], r0 41; DARWIN: __modsi3 42; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]] 43; DARWIN-O0: mov [[rem:r[0-9]+]], r0 44; WINDOWS: __rt_sdiv 45; WINDOWS: __rt_sdiv 46; WINDOWS-DEFAULT: add [[sum:r[0-9]+]], r1 47; WINDOWS-O0: mov [[rem:r[0-9]+]], r1 48 %rem8 = srem i32 %conv1, %conv 49; EABI: __aeabi_idivmod 50; DARWIN: __modsi3 51; WINDOWS: __rt_sdiv 52 %add = add nsw i32 %rem, %div 53 %add13 = add nsw i32 %add, %rem8 54 %conv14 = trunc i32 %add13 to i16 55; EABI: add r0{{.*}}r1 56; EABI: sxth r0, r0 57; DARWIN-DEFAULT: add [[res:r[0-9]+]], [[sum]], r0 58; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]] 59; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0 60; DARWIN: sxth r0, [[res]] 61; WINDOWS-DEFAULT: adds [[sum1:r[0-9]+]], [[sum]], r1 62; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], 63; WINDOWS-O0: add [[sum1:r[0-9]+]], r1 64; WINDOWS: sxth [[res:r[0-9]+]], [[sum1]] 65 ret i16 %conv14 66} 67 68define i32 @f32(i32 %a, i32 %b) { 69; EABI-LABEL: f32: 70; DARWIN-LABEL: f32: 71; WINDOWS-LABEL: f32: 72entry: 73 %div = sdiv i32 %a, %b 74 %rem = srem i32 %a, %b 75; EABI: __aeabi_idivmod 76; EABI: mov [[div:r[0-9]+]], r0 77; EABI: mov [[rem:r[0-9]+]], r1 78; DARWIN: ___divsi3 79; DARWIN: mov [[div:r[0-9]+]], r0 80; DARWIN: __modsi3 81; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]] 82; DARWIN-O0: mov [[rem:r[0-9]+]], r0 83; WINDOWS: __rt_sdiv 84; WINDOWS: mov [[div:r[0-9]+]], r0 85; WINDOWS: __rt_sdiv 86; WINDOWS-DEFAULT: add [[div]], r1 87 %rem1 = srem i32 %b, %a 88; EABI: __aeabi_idivmod 89; DARWIN: __modsi3 90; WINDOWS: __rt_sdiv 91 %add = add nsw i32 %rem, %div 92 %add2 = add nsw i32 %add, %rem1 93; EABI: add r0{{.*}}r1 94; DARWIN-DEFAULT: add r0, [[sum]], r0 95; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]] 96; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0 97; WINDOWS-DEFAULT: adds r0, [[div]], r1 98; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]] 99; WINDOWS-O0: add [[sum]], r1 100 ret i32 %add2 101} 102 103define i32 @uf(i32 %a, i32 %b) { 104; EABI-LABEL: uf: 105; DARWIN-LABEL: uf: 106; WINDOWS-LABEL: uf: 107entry: 108 %div = udiv i32 %a, %b 109 %rem = urem i32 %a, %b 110; EABI: __aeabi_uidivmod 111; DARWIN: ___udivsi3 112; DARWIN: mov [[div:r[0-9]+]], r0 113; DARWIN: __umodsi3 114; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]] 115; DARWIN-O0: mov [[rem:r[0-9]+]], r0 116; WINDOWS: __rt_udiv 117; WINDOWS: mov [[div:r[0-9]+]], r0 118; WINDOWS: __rt_udiv 119; WINDOWS-DEFAULT: add [[div]], r1 120 %rem1 = urem i32 %b, %a 121; EABI: __aeabi_uidivmod 122; DARWIN: __umodsi3 123; WINDOWS: __rt_udiv 124 %add = add nuw i32 %rem, %div 125 %add2 = add nuw i32 %add, %rem1 126; EABI: add r0{{.*}}r1 127; DARWIN-DEFAULT: add r0, [[sum]], r0 128; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]] 129; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0 130; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[div]], r1 131; WINDOWS-O0: adds [[sum:r[0-9]+]], 132; WINDOWS-O0: add [[sum]], r1 133 ret i32 %add2 134} 135 136define i64 @longf(i64 %a, i64 %b) { 137; EABI-LABEL: longf: 138; DARWIN-LABEL: longf: 139; WINDOWS-LABEL: longf: 140entry: 141 %div = sdiv i64 %a, %b 142 %rem = srem i64 %a, %b 143; EABI: __aeabi_ldivmod 144; EABI-NEXT: adds r0 145; EABI-NEXT: adc r1 146; EABI-NOT: __aeabi_ldivmod 147; DARWIN: ___divdi3 148; DARWIN: mov [[div1:r[0-9]+]], r0 149; DARWIN: mov [[div2:r[0-9]+]], r1 150; DARWIN: __moddi3 151; WINDOWS: __rt_sdiv64 152 %add = add nsw i64 %rem, %div 153; DARWIN: adds r0{{.*}}[[div1]] 154; DARWIN: adc r1{{.*}}[[div2]] 155; WINDOWS: adds r0, r0, r2 156; WINDOWS: adcs r1, r3 157 ret i64 %add 158} 159 160define i16 @shortf(i16 %a, i16 %b) { 161; EABI-LABEL: shortf: 162; DARWIN-LABEL: shortf: 163; WINDOWS-LABEL: shortf: 164entry: 165 %div = sdiv i16 %a, %b 166 %rem = srem i16 %a, %b 167; EABI: __aeabi_idivmod 168; DARWIN: ___divsi3 169; DARWIN: mov [[div1:r[0-9]+]], r0 170; DARWIN: __modsi3 171; WINDOWS: __rt_sdiv 172; WINDOWS: mov [[div:r[0-9]+]], r0 173; WINDOWS: __rt_sdiv 174 %add = add nsw i16 %rem, %div 175; EABI: add r0, r1 176; DARWIN: add r0{{.*}}[[div1]] 177; WINDOWS: adds r0, r1, [[div]] 178 ret i16 %add 179} 180 181define i32 @g1(i32 %a, i32 %b) { 182; EABI-LABEL: g1: 183; DARWIN-LABEL: g1: 184; WINDOWS-LABEL: g1: 185entry: 186 %div = sdiv i32 %a, %b 187 %rem = srem i32 %a, %b 188; EABI: __aeabi_idivmod 189; DARWIN: ___divsi3 190; DARWIN: mov [[sum:r[0-9]+]], r0 191; DARWIN: __modsi3 192; WINDOWS: __rt_sdiv 193; WINDOWS: mov [[div:r[0-9]+]], r0 194; WINDOWS: __rt_sdiv 195 %add = add nsw i32 %rem, %div 196; EABI: add r0{{.*}}r1 197; DARWIN: add r0{{.*}}[[sum]] 198; WINDOWS: adds r0, r1, [[div]] 199 ret i32 %add 200} 201 202; On both Darwin and Gnu, this is just a call to __modsi3 203define i32 @g2(i32 %a, i32 %b) { 204; EABI-LABEL: g2: 205; DARWIN-LABEL: g2: 206; WINDOWS-LABEL: g2: 207entry: 208 %rem = srem i32 %a, %b 209; EABI: __aeabi_idivmod 210; DARWIN: __modsi3 211; WINDOWS: __rt_sdiv 212 ret i32 %rem 213; EABI: mov r0, r1 214; WINDOWS: mov r0, r1 215} 216 217define i32 @g3(i32 %a, i32 %b) { 218; EABI-LABEL: g3: 219; DARWIN-LABEL: g3: 220; WINDOWS-LABEL: g3: 221entry: 222 %rem = srem i32 %a, %b 223; EABI: __aeabi_idivmod 224; EABI: mov [[mod:r[0-9]+]], r1 225; DARWIN: __modsi3 226; DARWIN: mov [[sum:r[0-9]+]], r0 227; WINDOWS: __rt_sdiv 228; WINDOWS: mov [[rem:r[0-9]+]], r1 229 %rem1 = srem i32 %b, %rem 230; EABI: __aeabi_idivmod 231; DARWIN: __modsi3 232; WINDOWS: __rt_sdiv 233 %add = add nsw i32 %rem1, %rem 234; EABI: add r0, r1, [[mod]] 235; DARWIN: add r0{{.*}}[[sum]] 236; WINDOWS: adds r0, r1, [[rem]] 237 ret i32 %add 238} 239 240define i32 @g4(i32 %a, i32 %b) { 241; EABI-LABEL: g4: 242; DARWIN-LABEL: g4: 243; WINDOWS-LABEL: g4: 244entry: 245 %div = sdiv i32 %a, %b 246; EABI: __aeabi_idiv{{$}} 247; EABI: mov [[div:r[0-9]+]], r0 248; DARWIN: ___divsi3 249; DARWIN: mov [[sum:r[0-9]+]], r0 250; WINDOWS: __rt_sdiv 251; WINDOWS: mov [[div:r[0-9]+]], r0 252 %rem = srem i32 %b, %div 253; EABI: __aeabi_idivmod 254; DARWIN: __modsi3 255; WINDOWS: __rt_sdiv 256 %add = add nsw i32 %rem, %div 257; EABI: add r0, r1, [[div]] 258; DARWIN: add r0{{.*}}[[sum]] 259; WINDOWS: adds r0, r1, [[div]] 260 ret i32 %add 261} 262