1; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefixes=ALL,LA32 2; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefixes=ALL,LA64 3 4define void @foo() noreturn nounwind { 5; ALL-LABEL: foo: 6; ALL: # %bb.0: # %entry 7; ALL-NEXT: .LBB0_1: # %loop 8; ALL-NEXT: # =>This Inner Loop Header: Depth=1 9; ALL-NEXT: b .LBB0_1 10entry: 11 br label %loop 12loop: 13 br label %loop 14} 15 16define void @foo_br_eq(i32 %a, ptr %b) nounwind { 17; LA32-LABEL: foo_br_eq: 18; LA32: # %bb.0: 19; LA32-NEXT: ld.w $a2, $a1, 0 20; LA32-NEXT: beq $a2, $a0, .LBB1_2 21; LA32-NEXT: b .LBB1_1 22; LA32-NEXT: .LBB1_1: # %test 23; LA32-NEXT: ld.w $a0, $a1, 0 24; LA32-NEXT: .LBB1_2: # %end 25; LA32-NEXT: jirl $zero, $ra, 0 26; 27; LA64-LABEL: foo_br_eq: 28; LA64: # %bb.0: 29; LA64-NEXT: ld.wu $a2, $a1, 0 30; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 31; LA64-NEXT: beq $a2, $a0, .LBB1_2 32; LA64-NEXT: b .LBB1_1 33; LA64-NEXT: .LBB1_1: # %test 34; LA64-NEXT: ld.w $a0, $a1, 0 35; LA64-NEXT: .LBB1_2: # %end 36; LA64-NEXT: jirl $zero, $ra, 0 37 %val = load volatile i32, ptr %b 38 %cc = icmp eq i32 %val, %a 39 br i1 %cc, label %end, label %test 40test: 41 %tmp = load volatile i32, ptr %b 42 br label %end 43 44end: 45 ret void 46} 47 48define void @foo_br_ne(i32 %a, ptr %b) nounwind { 49; LA32-LABEL: foo_br_ne: 50; LA32: # %bb.0: 51; LA32-NEXT: ld.w $a2, $a1, 0 52; LA32-NEXT: bne $a2, $a0, .LBB2_2 53; LA32-NEXT: b .LBB2_1 54; LA32-NEXT: .LBB2_1: # %test 55; LA32-NEXT: ld.w $a0, $a1, 0 56; LA32-NEXT: .LBB2_2: # %end 57; LA32-NEXT: jirl $zero, $ra, 0 58; 59; LA64-LABEL: foo_br_ne: 60; LA64: # %bb.0: 61; LA64-NEXT: ld.wu $a2, $a1, 0 62; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 63; LA64-NEXT: bne $a2, $a0, .LBB2_2 64; LA64-NEXT: b .LBB2_1 65; LA64-NEXT: .LBB2_1: # %test 66; LA64-NEXT: ld.w $a0, $a1, 0 67; LA64-NEXT: .LBB2_2: # %end 68; LA64-NEXT: jirl $zero, $ra, 0 69 %val = load volatile i32, ptr %b 70 %cc = icmp ne i32 %val, %a 71 br i1 %cc, label %end, label %test 72test: 73 %tmp = load volatile i32, ptr %b 74 br label %end 75 76end: 77 ret void 78} 79 80define void @foo_br_slt(i32 %a, ptr %b) nounwind { 81; LA32-LABEL: foo_br_slt: 82; LA32: # %bb.0: 83; LA32-NEXT: ld.w $a2, $a1, 0 84; LA32-NEXT: blt $a2, $a0, .LBB3_2 85; LA32-NEXT: b .LBB3_1 86; LA32-NEXT: .LBB3_1: # %test 87; LA32-NEXT: ld.w $a0, $a1, 0 88; LA32-NEXT: .LBB3_2: # %end 89; LA32-NEXT: jirl $zero, $ra, 0 90; 91; LA64-LABEL: foo_br_slt: 92; LA64: # %bb.0: 93; LA64-NEXT: ld.w $a2, $a1, 0 94; LA64-NEXT: addi.w $a0, $a0, 0 95; LA64-NEXT: blt $a2, $a0, .LBB3_2 96; LA64-NEXT: b .LBB3_1 97; LA64-NEXT: .LBB3_1: # %test 98; LA64-NEXT: ld.w $a0, $a1, 0 99; LA64-NEXT: .LBB3_2: # %end 100; LA64-NEXT: jirl $zero, $ra, 0 101 %val = load volatile i32, ptr %b 102 %cc = icmp slt i32 %val, %a 103 br i1 %cc, label %end, label %test 104test: 105 %tmp = load volatile i32, ptr %b 106 br label %end 107 108end: 109 ret void 110} 111 112define void @foo_br_sge(i32 %a, ptr %b) nounwind { 113; LA32-LABEL: foo_br_sge: 114; LA32: # %bb.0: 115; LA32-NEXT: ld.w $a2, $a1, 0 116; LA32-NEXT: bge $a2, $a0, .LBB4_2 117; LA32-NEXT: b .LBB4_1 118; LA32-NEXT: .LBB4_1: # %test 119; LA32-NEXT: ld.w $a0, $a1, 0 120; LA32-NEXT: .LBB4_2: # %end 121; LA32-NEXT: jirl $zero, $ra, 0 122; 123; LA64-LABEL: foo_br_sge: 124; LA64: # %bb.0: 125; LA64-NEXT: ld.w $a2, $a1, 0 126; LA64-NEXT: addi.w $a0, $a0, 0 127; LA64-NEXT: bge $a2, $a0, .LBB4_2 128; LA64-NEXT: b .LBB4_1 129; LA64-NEXT: .LBB4_1: # %test 130; LA64-NEXT: ld.w $a0, $a1, 0 131; LA64-NEXT: .LBB4_2: # %end 132; LA64-NEXT: jirl $zero, $ra, 0 133 %val = load volatile i32, ptr %b 134 %cc = icmp sge i32 %val, %a 135 br i1 %cc, label %end, label %test 136test: 137 %tmp = load volatile i32, ptr %b 138 br label %end 139 140end: 141 ret void 142} 143 144define void @foo_br_ult(i32 %a, ptr %b) nounwind { 145; LA32-LABEL: foo_br_ult: 146; LA32: # %bb.0: 147; LA32-NEXT: ld.w $a2, $a1, 0 148; LA32-NEXT: bltu $a2, $a0, .LBB5_2 149; LA32-NEXT: b .LBB5_1 150; LA32-NEXT: .LBB5_1: # %test 151; LA32-NEXT: ld.w $a0, $a1, 0 152; LA32-NEXT: .LBB5_2: # %end 153; LA32-NEXT: jirl $zero, $ra, 0 154; 155; LA64-LABEL: foo_br_ult: 156; LA64: # %bb.0: 157; LA64-NEXT: ld.wu $a2, $a1, 0 158; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 159; LA64-NEXT: bltu $a2, $a0, .LBB5_2 160; LA64-NEXT: b .LBB5_1 161; LA64-NEXT: .LBB5_1: # %test 162; LA64-NEXT: ld.w $a0, $a1, 0 163; LA64-NEXT: .LBB5_2: # %end 164; LA64-NEXT: jirl $zero, $ra, 0 165 %val = load volatile i32, ptr %b 166 %cc = icmp ult i32 %val, %a 167 br i1 %cc, label %end, label %test 168test: 169 %tmp = load volatile i32, ptr %b 170 br label %end 171 172end: 173 ret void 174} 175 176define void @foo_br_uge(i32 %a, ptr %b) nounwind { 177; LA32-LABEL: foo_br_uge: 178; LA32: # %bb.0: 179; LA32-NEXT: ld.w $a2, $a1, 0 180; LA32-NEXT: bgeu $a2, $a0, .LBB6_2 181; LA32-NEXT: b .LBB6_1 182; LA32-NEXT: .LBB6_1: # %test 183; LA32-NEXT: ld.w $a0, $a1, 0 184; LA32-NEXT: .LBB6_2: # %end 185; LA32-NEXT: jirl $zero, $ra, 0 186; 187; LA64-LABEL: foo_br_uge: 188; LA64: # %bb.0: 189; LA64-NEXT: ld.wu $a2, $a1, 0 190; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 191; LA64-NEXT: bgeu $a2, $a0, .LBB6_2 192; LA64-NEXT: b .LBB6_1 193; LA64-NEXT: .LBB6_1: # %test 194; LA64-NEXT: ld.w $a0, $a1, 0 195; LA64-NEXT: .LBB6_2: # %end 196; LA64-NEXT: jirl $zero, $ra, 0 197 %val = load volatile i32, ptr %b 198 %cc = icmp uge i32 %val, %a 199 br i1 %cc, label %end, label %test 200test: 201 %tmp = load volatile i32, ptr %b 202 br label %end 203 204end: 205 ret void 206} 207 208;; Check for condition codes that don't have a matching instruction. 209define void @foo_br_sgt(i32 %a, ptr %b) nounwind { 210; LA32-LABEL: foo_br_sgt: 211; LA32: # %bb.0: 212; LA32-NEXT: ld.w $a2, $a1, 0 213; LA32-NEXT: blt $a0, $a2, .LBB7_2 214; LA32-NEXT: b .LBB7_1 215; LA32-NEXT: .LBB7_1: # %test 216; LA32-NEXT: ld.w $a0, $a1, 0 217; LA32-NEXT: .LBB7_2: # %end 218; LA32-NEXT: jirl $zero, $ra, 0 219; 220; LA64-LABEL: foo_br_sgt: 221; LA64: # %bb.0: 222; LA64-NEXT: ld.w $a2, $a1, 0 223; LA64-NEXT: addi.w $a0, $a0, 0 224; LA64-NEXT: blt $a0, $a2, .LBB7_2 225; LA64-NEXT: b .LBB7_1 226; LA64-NEXT: .LBB7_1: # %test 227; LA64-NEXT: ld.w $a0, $a1, 0 228; LA64-NEXT: .LBB7_2: # %end 229; LA64-NEXT: jirl $zero, $ra, 0 230 %val = load volatile i32, ptr %b 231 %cc = icmp sgt i32 %val, %a 232 br i1 %cc, label %end, label %test 233test: 234 %tmp = load volatile i32, ptr %b 235 br label %end 236 237end: 238 ret void 239} 240 241define void @foo_br_sle(i32 %a, ptr %b) nounwind { 242; LA32-LABEL: foo_br_sle: 243; LA32: # %bb.0: 244; LA32-NEXT: ld.w $a2, $a1, 0 245; LA32-NEXT: bge $a0, $a2, .LBB8_2 246; LA32-NEXT: b .LBB8_1 247; LA32-NEXT: .LBB8_1: # %test 248; LA32-NEXT: ld.w $a0, $a1, 0 249; LA32-NEXT: .LBB8_2: # %end 250; LA32-NEXT: jirl $zero, $ra, 0 251; 252; LA64-LABEL: foo_br_sle: 253; LA64: # %bb.0: 254; LA64-NEXT: ld.w $a2, $a1, 0 255; LA64-NEXT: addi.w $a0, $a0, 0 256; LA64-NEXT: bge $a0, $a2, .LBB8_2 257; LA64-NEXT: b .LBB8_1 258; LA64-NEXT: .LBB8_1: # %test 259; LA64-NEXT: ld.w $a0, $a1, 0 260; LA64-NEXT: .LBB8_2: # %end 261; LA64-NEXT: jirl $zero, $ra, 0 262 %val = load volatile i32, ptr %b 263 %cc = icmp sle i32 %val, %a 264 br i1 %cc, label %end, label %test 265test: 266 %tmp = load volatile i32, ptr %b 267 br label %end 268 269end: 270 ret void 271} 272 273define void @foo_br_ugt(i32 %a, ptr %b) nounwind { 274; LA32-LABEL: foo_br_ugt: 275; LA32: # %bb.0: 276; LA32-NEXT: ld.w $a2, $a1, 0 277; LA32-NEXT: bltu $a0, $a2, .LBB9_2 278; LA32-NEXT: b .LBB9_1 279; LA32-NEXT: .LBB9_1: # %test 280; LA32-NEXT: ld.w $a0, $a1, 0 281; LA32-NEXT: .LBB9_2: # %end 282; LA32-NEXT: jirl $zero, $ra, 0 283; 284; LA64-LABEL: foo_br_ugt: 285; LA64: # %bb.0: 286; LA64-NEXT: ld.wu $a2, $a1, 0 287; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 288; LA64-NEXT: bltu $a0, $a2, .LBB9_2 289; LA64-NEXT: b .LBB9_1 290; LA64-NEXT: .LBB9_1: # %test 291; LA64-NEXT: ld.w $a0, $a1, 0 292; LA64-NEXT: .LBB9_2: # %end 293; LA64-NEXT: jirl $zero, $ra, 0 294 %val = load volatile i32, ptr %b 295 %cc = icmp ugt i32 %val, %a 296 br i1 %cc, label %end, label %test 297test: 298 %tmp = load volatile i32, ptr %b 299 br label %end 300 301end: 302 ret void 303} 304 305define void @foo_br_ule(i32 %a, ptr %b) nounwind { 306; LA32-LABEL: foo_br_ule: 307; LA32: # %bb.0: 308; LA32-NEXT: ld.w $a2, $a1, 0 309; LA32-NEXT: bgeu $a0, $a2, .LBB10_2 310; LA32-NEXT: b .LBB10_1 311; LA32-NEXT: .LBB10_1: # %test 312; LA32-NEXT: ld.w $a0, $a1, 0 313; LA32-NEXT: .LBB10_2: # %end 314; LA32-NEXT: jirl $zero, $ra, 0 315; 316; LA64-LABEL: foo_br_ule: 317; LA64: # %bb.0: 318; LA64-NEXT: ld.wu $a2, $a1, 0 319; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 320; LA64-NEXT: bgeu $a0, $a2, .LBB10_2 321; LA64-NEXT: b .LBB10_1 322; LA64-NEXT: .LBB10_1: # %test 323; LA64-NEXT: ld.w $a0, $a1, 0 324; LA64-NEXT: .LBB10_2: # %end 325; LA64-NEXT: jirl $zero, $ra, 0 326 %val = load volatile i32, ptr %b 327 %cc = icmp ule i32 %val, %a 328 br i1 %cc, label %end, label %test 329test: 330 %tmp = load volatile i32, ptr %b 331 br label %end 332 333end: 334 ret void 335} 336 337;; Check the case of a branch where the condition was generated in another 338;; function. 339define void @foo_br_cc(ptr %a, i1 %cc) nounwind { 340; ALL-LABEL: foo_br_cc: 341; ALL: # %bb.0: 342; ALL-NEXT: ld.w $a2, $a0, 0 343; ALL-NEXT: andi $a1, $a1, 1 344; ALL-NEXT: bnez $a1, .LBB11_2 345; ALL-NEXT: b .LBB11_1 346; ALL-NEXT: .LBB11_1: # %test 347; ALL-NEXT: ld.w $a0, $a0, 0 348; ALL-NEXT: .LBB11_2: # %end 349; ALL-NEXT: jirl $zero, $ra, 0 350 %val = load volatile i32, ptr %a 351 br i1 %cc, label %end, label %test 352test: 353 %tmp = load volatile i32, ptr %a 354 br label %end 355 356end: 357 ret void 358} 359