1; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 -verify-machineinstrs | FileCheck %s 2; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr9 -verify-machineinstrs | FileCheck %s 3; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-PWR8 -implicit-check-not mod[us][wd] 4 5@mod_resultsw = common local_unnamed_addr global i32 0, align 4 6@mod_resultud = common local_unnamed_addr global i64 0, align 8 7@div_resultsw = common local_unnamed_addr global i32 0, align 4 8@mod_resultuw = common local_unnamed_addr global i32 0, align 4 9@div_resultuw = common local_unnamed_addr global i32 0, align 4 10@div_resultsd = common local_unnamed_addr global i64 0, align 8 11@mod_resultsd = common local_unnamed_addr global i64 0, align 8 12@div_resultud = common local_unnamed_addr global i64 0, align 8 13 14; Function Attrs: norecurse nounwind 15define void @modulo_sw(i32 signext %a, i32 signext %b) local_unnamed_addr { 16entry: 17 %rem = srem i32 %a, %b 18 store i32 %rem, i32* @mod_resultsw, align 4 19 ret void 20; CHECK-LABEL: modulo_sw 21; CHECK: modsw {{[0-9]+}}, 3, 4 22; CHECK: blr 23; CHECK-PWR8-LABEL: modulo_sw 24; CHECK-PWR8: div 25; CHECK-PWR8: mull 26; CHECK-PWR8: sub 27; CHECK-PWR8: blr 28} 29 30; Function Attrs: norecurse nounwind readnone 31define zeroext i32 @modulo_uw(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr { 32entry: 33 %rem = urem i32 %a, %b 34 ret i32 %rem 35; CHECK-LABEL: modulo_uw 36; CHECK: moduw {{[0-9]+}}, 3, 4 37; CHECK: blr 38; CHECK-PWR8-LABEL: modulo_uw 39; CHECK-PWR8: div 40; CHECK-PWR8: mull 41; CHECK-PWR8: sub 42; CHECK-PWR8: blr 43} 44 45; Function Attrs: norecurse nounwind readnone 46define i64 @modulo_sd(i64 %a, i64 %b) local_unnamed_addr { 47entry: 48 %rem = srem i64 %a, %b 49 ret i64 %rem 50; CHECK-LABEL: modulo_sd 51; CHECK: modsd {{[0-9]+}}, 3, 4 52; CHECK: blr 53; CHECK-PWR8-LABEL: modulo_sd 54; CHECK-PWR8: div 55; CHECK-PWR8: mull 56; CHECK-PWR8: sub 57; CHECK-PWR8: blr 58} 59 60; Function Attrs: norecurse nounwind 61define void @modulo_ud(i64 %a, i64 %b) local_unnamed_addr { 62entry: 63 %rem = urem i64 %a, %b 64 store i64 %rem, i64* @mod_resultud, align 8 65 ret void 66; CHECK-LABEL: modulo_ud 67; CHECK: modud {{[0-9]+}}, 3, 4 68; CHECK: blr 69; CHECK-PWR8-LABEL: modulo_ud 70; CHECK-PWR8: div 71; CHECK-PWR8: mull 72; CHECK-PWR8: sub 73; CHECK-PWR8: blr 74} 75 76; Function Attrs: norecurse nounwind 77define void @modulo_div_sw(i32 signext %a, i32 signext %b) local_unnamed_addr { 78entry: 79 %rem = srem i32 %a, %b 80 store i32 %rem, i32* @mod_resultsw, align 4 81 %div = sdiv i32 %a, %b 82 store i32 %div, i32* @div_resultsw, align 4 83 ret void 84; CHECK-LABEL: modulo_div_sw 85; CHECK-NOT: modsw 86; CHECK: div 87; CHECK-NOT: modsw 88; CHECK: mull 89; CHECK-NOT: modsw 90; CHECK: sub 91; CHECK: blr 92; CHECK-PWR8-LABEL: modulo_div_sw 93; CHECK-PWR8: div 94; CHECK-PWR8: mull 95; CHECK-PWR8: sub 96; CHECK-PWR8: blr 97} 98 99; Function Attrs: norecurse nounwind 100define void @modulo_div_abc_sw(i32 signext %a, i32 signext %b, i32 signext %c) local_unnamed_addr { 101entry: 102 %rem = srem i32 %a, %c 103 store i32 %rem, i32* @mod_resultsw, align 4 104 %div = sdiv i32 %b, %c 105 store i32 %div, i32* @div_resultsw, align 4 106 ret void 107; CHECK-LABEL: modulo_div_abc_sw 108; CHECK: modsw {{[0-9]+}}, 3, 5 109; CHECK: blr 110; CHECK-PWR8-LABEL: modulo_div_abc_sw 111; CHECK-PWR8: div 112; CHECK-PWR8: mull 113; CHECK-PWR8: sub 114; CHECK-PWR8: blr 115} 116 117; Function Attrs: norecurse nounwind 118define void @modulo_div_uw(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr { 119entry: 120 %rem = urem i32 %a, %b 121 store i32 %rem, i32* @mod_resultuw, align 4 122 %div = udiv i32 %a, %b 123 store i32 %div, i32* @div_resultuw, align 4 124 ret void 125; CHECK-LABEL: modulo_div_uw 126; CHECK-NOT: modsw 127; CHECK: div 128; CHECK-NOT: modsw 129; CHECK: mull 130; CHECK-NOT: modsw 131; CHECK: sub 132; CHECK: blr 133; CHECK-PWR8-LABEL: modulo_div_uw 134; CHECK-PWR8: div 135; CHECK-PWR8: mull 136; CHECK-PWR8: sub 137; CHECK-PWR8: blr 138} 139 140; Function Attrs: norecurse nounwind 141define void @modulo_div_swuw(i32 signext %a, i32 signext %b) local_unnamed_addr { 142entry: 143 %rem = srem i32 %a, %b 144 store i32 %rem, i32* @mod_resultsw, align 4 145 %div = udiv i32 %a, %b 146 store i32 %div, i32* @div_resultsw, align 4 147 ret void 148; CHECK-LABEL: modulo_div_swuw 149; CHECK: modsw {{[0-9]+}}, 3, 4 150; CHECK: blr 151; CHECK-PWR8-LABEL: modulo_div_swuw 152; CHECK-PWR8: div 153; CHECK-PWR8: mull 154; CHECK-PWR8: sub 155; CHECK-PWR8: blr 156} 157 158; Function Attrs: norecurse nounwind 159define void @modulo_div_udsd(i64 %a, i64 %b) local_unnamed_addr { 160entry: 161 %rem = urem i64 %a, %b 162 store i64 %rem, i64* @mod_resultud, align 8 163 %div = sdiv i64 %a, %b 164 store i64 %div, i64* @div_resultsd, align 8 165 ret void 166; CHECK-LABEL: modulo_div_udsd 167; CHECK: modud {{[0-9]+}}, 3, 4 168; CHECK: blr 169; CHECK-PWR8-LABEL: modulo_div_udsd 170; CHECK-PWR8: div 171; CHECK-PWR8: mull 172; CHECK-PWR8: sub 173; CHECK-PWR8: blr 174} 175 176; Function Attrs: norecurse nounwind 177define void @modulo_const32_sw(i32 signext %a) local_unnamed_addr { 178entry: 179 %rem = srem i32 %a, 32 180 store i32 %rem, i32* @mod_resultsw, align 4 181 ret void 182; CHECK-LABEL: modulo_const32_sw 183; CHECK-NOT: modsw 184; CHECK: srawi 185; CHECK-NOT: modsw 186; CHECK: addze 187; CHECK-NOT: modsw 188; CHECK: slwi 189; CHECK-NOT: modsw 190; CHECK: subf 191; CHECK-NOT: modsw 192; CHECK: blr 193; CHECK-PWR8-LABEL: modulo_const32_sw 194; CHECK-PWR8: srawi 195; CHECK-PWR8: addze 196; CHECK-PWR8: slwi 197; CHECK-PWR8: subf 198; CHECK-PWR8: blr 199} 200 201; Function Attrs: norecurse nounwind readnone 202define signext i32 @modulo_const3_sw(i32 signext %a) local_unnamed_addr { 203entry: 204 %rem = srem i32 %a, 3 205 ret i32 %rem 206; CHECK-LABEL: modulo_const3_sw 207; CHECK-NOT: modsw 208; CHECK: mull 209; CHECK-NOT: modsw 210; CHECK: sub 211; CHECK-NOT: modsw 212; CHECK: blr 213; CHECK-PWR8-LABEL: modulo_const3_sw 214; CHECK-PWR8: mull 215; CHECK-PWR8: sub 216; CHECK-PWR8: blr 217} 218 219; Function Attrs: norecurse nounwind readnone 220define signext i32 @const2_modulo_sw(i32 signext %a) local_unnamed_addr { 221entry: 222 %rem = srem i32 2, %a 223 ret i32 %rem 224; CHECK-LABEL: const2_modulo_sw 225; CHECK: modsw {{[0-9]+}}, {{[0-9]+}}, 3 226; CHECK: blr 227; CHECK-PWR8-LABEL: const2_modulo_sw 228; CHECK-PWR8: div 229; CHECK-PWR8: mull 230; CHECK-PWR8: sub 231; CHECK-PWR8: blr 232} 233 234; Function Attrs: norecurse nounwind 235; FIXME On power 9 this test will still produce modsw because the divide is in 236; a different block than the remainder. Due to the nature of the SDAG we cannot 237; see the div in the other block. 238define void @blocks_modulo_div_sw(i32 signext %a, i32 signext %b, i32 signext %c) local_unnamed_addr { 239entry: 240 %div = sdiv i32 %a, %b 241 store i32 %div, i32* @div_resultsw, align 4 242 %cmp = icmp sgt i32 %c, 0 243 br i1 %cmp, label %if.then, label %if.end 244 245if.then: ; preds = %entry 246 %rem = srem i32 %a, %b 247 store i32 %rem, i32* @mod_resultsw, align 4 248 br label %if.end 249 250if.end: ; preds = %if.then, %entry 251 ret void 252; CHECK-LABEL: blocks_modulo_div_sw 253; CHECK: div 254; CHECK: modsw {{[0-9]+}}, 3, 4 255; CHECK: blr 256; CHECK-PWR8-LABEL: blocks_modulo_div_sw 257; CHECK-PWR8: div 258; CHECK-PWR8: mull 259; CHECK-PWR8: sub 260; CHECK-PWR8: blr 261} 262 263 264