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