1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 2; RUN: llc -mtriple=riscv64 < %s | FileCheck -check-prefixes=RV64,NO-ZBA %s 3; RUN: llc -mtriple=riscv64 -mattr=+zba < %s | FileCheck -check-prefixes=RV64,ZBA %s 4 5define void @add_sext_shl_moreOneUse_add(ptr %array1, i32 %a, i32 %b) { 6; NO-ZBA-LABEL: add_sext_shl_moreOneUse_add: 7; NO-ZBA: # %bb.0: # %entry 8; NO-ZBA-NEXT: addi a3, a1, 5 9; NO-ZBA-NEXT: sext.w a1, a1 10; NO-ZBA-NEXT: slli a1, a1, 2 11; NO-ZBA-NEXT: add a0, a1, a0 12; NO-ZBA-NEXT: sw a2, 20(a0) 13; NO-ZBA-NEXT: sw a2, 24(a0) 14; NO-ZBA-NEXT: sw a3, 140(a0) 15; NO-ZBA-NEXT: ret 16; 17; ZBA-LABEL: add_sext_shl_moreOneUse_add: 18; ZBA: # %bb.0: # %entry 19; ZBA-NEXT: addi a3, a1, 5 20; ZBA-NEXT: sext.w a1, a1 21; ZBA-NEXT: sh2add a0, a1, a0 22; ZBA-NEXT: sw a2, 20(a0) 23; ZBA-NEXT: sw a2, 24(a0) 24; ZBA-NEXT: sw a3, 140(a0) 25; ZBA-NEXT: ret 26entry: 27 %add = add nsw i32 %a, 5 28 %idxprom = sext i32 %add to i64 29 %arrayidx = getelementptr inbounds i32, ptr %array1, i64 %idxprom 30 store i32 %b, ptr %arrayidx 31 %add3 = add nsw i32 %a, 6 32 %idxprom4 = sext i32 %add3 to i64 33 %arrayidx5 = getelementptr inbounds i32, ptr %array1, i64 %idxprom4 34 store i32 %b, ptr %arrayidx5 35 %add6 = add nsw i32 %a, 35 36 %idxprom7 = sext i32 %add6 to i64 37 %arrayidx8 = getelementptr inbounds i32, ptr %array1, i64 %idxprom7 38 store i32 %add, ptr %arrayidx8 39 ret void 40} 41 42define void @add_sext_shl_moreOneUse_addexceedsign12(ptr %array1, i32 %a, i32 %b) { 43; NO-ZBA-LABEL: add_sext_shl_moreOneUse_addexceedsign12: 44; NO-ZBA: # %bb.0: # %entry 45; NO-ZBA-NEXT: addi a3, a1, 2047 46; NO-ZBA-NEXT: lui a4, 2 47; NO-ZBA-NEXT: sext.w a1, a1 48; NO-ZBA-NEXT: addi a3, a3, 1 49; NO-ZBA-NEXT: slli a1, a1, 2 50; NO-ZBA-NEXT: add a0, a0, a4 51; NO-ZBA-NEXT: add a0, a0, a1 52; NO-ZBA-NEXT: sw a2, 0(a0) 53; NO-ZBA-NEXT: sw a3, 4(a0) 54; NO-ZBA-NEXT: sw a2, 120(a0) 55; NO-ZBA-NEXT: ret 56; 57; ZBA-LABEL: add_sext_shl_moreOneUse_addexceedsign12: 58; ZBA: # %bb.0: # %entry 59; ZBA-NEXT: addi a3, a1, 2047 60; ZBA-NEXT: lui a4, 2 61; ZBA-NEXT: sext.w a1, a1 62; ZBA-NEXT: addi a3, a3, 1 63; ZBA-NEXT: sh2add a0, a1, a0 64; ZBA-NEXT: add a0, a0, a4 65; ZBA-NEXT: sw a2, 0(a0) 66; ZBA-NEXT: sw a3, 4(a0) 67; ZBA-NEXT: sw a2, 120(a0) 68; ZBA-NEXT: ret 69entry: 70 %add = add nsw i32 %a, 2048 71 %idxprom = sext i32 %add to i64 72 %arrayidx = getelementptr inbounds i32, ptr %array1, i64 %idxprom 73 store i32 %b, ptr %arrayidx 74 %0 = sext i32 %a to i64 75 %1 = getelementptr i32, ptr %array1, i64 %0 76 %arrayidx3 = getelementptr i8, ptr %1, i64 8196 77 store i32 %add, ptr %arrayidx3 78 %arrayidx6 = getelementptr i8, ptr %1, i64 8312 79 store i32 %b, ptr %arrayidx6 80 ret void 81} 82 83define void @add_sext_shl_moreOneUse_sext(ptr %array1, i32 %a, i32 %b) { 84; NO-ZBA-LABEL: add_sext_shl_moreOneUse_sext: 85; NO-ZBA: # %bb.0: # %entry 86; NO-ZBA-NEXT: sext.w a1, a1 87; NO-ZBA-NEXT: addi a3, a1, 5 88; NO-ZBA-NEXT: slli a1, a1, 2 89; NO-ZBA-NEXT: add a0, a1, a0 90; NO-ZBA-NEXT: sw a2, 20(a0) 91; NO-ZBA-NEXT: sw a2, 24(a0) 92; NO-ZBA-NEXT: sd a3, 140(a0) 93; NO-ZBA-NEXT: ret 94; 95; ZBA-LABEL: add_sext_shl_moreOneUse_sext: 96; ZBA: # %bb.0: # %entry 97; ZBA-NEXT: sext.w a1, a1 98; ZBA-NEXT: addi a3, a1, 5 99; ZBA-NEXT: sh2add a0, a1, a0 100; ZBA-NEXT: sw a2, 20(a0) 101; ZBA-NEXT: sw a2, 24(a0) 102; ZBA-NEXT: sd a3, 140(a0) 103; ZBA-NEXT: ret 104entry: 105 %add = add nsw i32 %a, 5 106 %idxprom = sext i32 %add to i64 107 %arrayidx = getelementptr inbounds i32, ptr %array1, i64 %idxprom 108 store i32 %b, ptr %arrayidx 109 %add3 = add nsw i32 %a, 6 110 %idxprom4 = sext i32 %add3 to i64 111 %arrayidx5 = getelementptr inbounds i32, ptr %array1, i64 %idxprom4 112 store i32 %b, ptr %arrayidx5 113 %add6 = add nsw i32 %a, 35 114 %idxprom7 = sext i32 %add6 to i64 115 %arrayidx8 = getelementptr inbounds i32, ptr %array1, i64 %idxprom7 116 store i64 %idxprom, ptr %arrayidx8 117 ret void 118} 119 120; test of jumpping, find add's operand has one more use can simplified 121define void @add_sext_shl_moreOneUse_add_inSelect(ptr %array1, i32 signext %a, i32 %b, i32 signext %x) { 122; NO-ZBA-LABEL: add_sext_shl_moreOneUse_add_inSelect: 123; NO-ZBA: # %bb.0: # %entry 124; NO-ZBA-NEXT: addi a4, a1, 5 125; NO-ZBA-NEXT: mv a5, a4 126; NO-ZBA-NEXT: bgtz a3, .LBB3_2 127; NO-ZBA-NEXT: # %bb.1: # %entry 128; NO-ZBA-NEXT: mv a5, a2 129; NO-ZBA-NEXT: .LBB3_2: # %entry 130; NO-ZBA-NEXT: slli a1, a1, 2 131; NO-ZBA-NEXT: add a0, a1, a0 132; NO-ZBA-NEXT: sw a5, 20(a0) 133; NO-ZBA-NEXT: sw a5, 24(a0) 134; NO-ZBA-NEXT: sw a4, 140(a0) 135; NO-ZBA-NEXT: ret 136; 137; ZBA-LABEL: add_sext_shl_moreOneUse_add_inSelect: 138; ZBA: # %bb.0: # %entry 139; ZBA-NEXT: addi a4, a1, 5 140; ZBA-NEXT: mv a5, a4 141; ZBA-NEXT: bgtz a3, .LBB3_2 142; ZBA-NEXT: # %bb.1: # %entry 143; ZBA-NEXT: mv a5, a2 144; ZBA-NEXT: .LBB3_2: # %entry 145; ZBA-NEXT: sh2add a0, a1, a0 146; ZBA-NEXT: sw a5, 20(a0) 147; ZBA-NEXT: sw a5, 24(a0) 148; ZBA-NEXT: sw a4, 140(a0) 149; ZBA-NEXT: ret 150entry: 151 %add = add nsw i32 %a, 5 152 %cmp = icmp sgt i32 %x, 0 153 %idxprom = sext i32 %add to i64 154 %arrayidx = getelementptr inbounds i32, ptr %array1, i64 %idxprom 155 %add.b = select i1 %cmp, i32 %add, i32 %b 156 store i32 %add.b, ptr %arrayidx 157 %add5 = add nsw i32 %a, 6 158 %idxprom6 = sext i32 %add5 to i64 159 %arrayidx7 = getelementptr inbounds i32, ptr %array1, i64 %idxprom6 160 store i32 %add.b, ptr %arrayidx7 161 %add8 = add nsw i32 %a, 35 162 %idxprom9 = sext i32 %add8 to i64 163 %arrayidx10 = getelementptr inbounds i32, ptr %array1, i64 %idxprom9 164 store i32 %add, ptr %arrayidx10 165 ret void 166} 167 168define void @add_sext_shl_moreOneUse_add_inSelect_addexceedsign12(ptr %array1, i32 signext %a, i32 %b, i32 signext %x) { 169; NO-ZBA-LABEL: add_sext_shl_moreOneUse_add_inSelect_addexceedsign12: 170; NO-ZBA: # %bb.0: # %entry 171; NO-ZBA-NEXT: addi a4, a1, 2047 172; NO-ZBA-NEXT: lui a5, 2 173; NO-ZBA-NEXT: slli a6, a1, 2 174; NO-ZBA-NEXT: addi a1, a4, 1 175; NO-ZBA-NEXT: add a0, a0, a6 176; NO-ZBA-NEXT: add a0, a0, a5 177; NO-ZBA-NEXT: mv a4, a1 178; NO-ZBA-NEXT: bgtz a3, .LBB4_2 179; NO-ZBA-NEXT: # %bb.1: # %entry 180; NO-ZBA-NEXT: mv a4, a2 181; NO-ZBA-NEXT: .LBB4_2: # %entry 182; NO-ZBA-NEXT: sw a4, 0(a0) 183; NO-ZBA-NEXT: sw a4, 4(a0) 184; NO-ZBA-NEXT: sw a1, 120(a0) 185; NO-ZBA-NEXT: ret 186; 187; ZBA-LABEL: add_sext_shl_moreOneUse_add_inSelect_addexceedsign12: 188; ZBA: # %bb.0: # %entry 189; ZBA-NEXT: addi a4, a1, 2047 190; ZBA-NEXT: lui a5, 2 191; ZBA-NEXT: addi a4, a4, 1 192; ZBA-NEXT: sh2add a0, a1, a0 193; ZBA-NEXT: add a0, a0, a5 194; ZBA-NEXT: mv a1, a4 195; ZBA-NEXT: bgtz a3, .LBB4_2 196; ZBA-NEXT: # %bb.1: # %entry 197; ZBA-NEXT: mv a1, a2 198; ZBA-NEXT: .LBB4_2: # %entry 199; ZBA-NEXT: sw a1, 0(a0) 200; ZBA-NEXT: sw a1, 4(a0) 201; ZBA-NEXT: sw a4, 120(a0) 202; ZBA-NEXT: ret 203entry: 204 %add = add nsw i32 %a, 2048 205 %cmp = icmp sgt i32 %x, 0 206 %idxprom = sext i32 %add to i64 207 %arrayidx = getelementptr inbounds i32, ptr %array1, i64 %idxprom 208 %add.b = select i1 %cmp, i32 %add, i32 %b 209 store i32 %add.b, ptr %arrayidx 210 %0 = sext i32 %a to i64 211 %1 = getelementptr i32, ptr %array1, i64 %0 212 %arrayidx7 = getelementptr i8, ptr %1, i64 8196 213 store i32 %add.b, ptr %arrayidx7 214 %arrayidx10 = getelementptr i8, ptr %1, i64 8312 215 store i32 %add, ptr %arrayidx10 216 ret void 217} 218 219define void @add_shl_moreOneUse_inSelect(ptr %array1, i64 %a, i64 %b, i64 %x) { 220; NO-ZBA-LABEL: add_shl_moreOneUse_inSelect: 221; NO-ZBA: # %bb.0: # %entry 222; NO-ZBA-NEXT: addi a4, a1, 5 223; NO-ZBA-NEXT: mv a5, a4 224; NO-ZBA-NEXT: bgtz a3, .LBB5_2 225; NO-ZBA-NEXT: # %bb.1: # %entry 226; NO-ZBA-NEXT: mv a5, a2 227; NO-ZBA-NEXT: .LBB5_2: # %entry 228; NO-ZBA-NEXT: slli a1, a1, 3 229; NO-ZBA-NEXT: add a0, a1, a0 230; NO-ZBA-NEXT: sd a5, 40(a0) 231; NO-ZBA-NEXT: sd a5, 48(a0) 232; NO-ZBA-NEXT: sd a4, 280(a0) 233; NO-ZBA-NEXT: ret 234; 235; ZBA-LABEL: add_shl_moreOneUse_inSelect: 236; ZBA: # %bb.0: # %entry 237; ZBA-NEXT: addi a4, a1, 5 238; ZBA-NEXT: mv a5, a4 239; ZBA-NEXT: bgtz a3, .LBB5_2 240; ZBA-NEXT: # %bb.1: # %entry 241; ZBA-NEXT: mv a5, a2 242; ZBA-NEXT: .LBB5_2: # %entry 243; ZBA-NEXT: sh3add a0, a1, a0 244; ZBA-NEXT: sd a5, 40(a0) 245; ZBA-NEXT: sd a5, 48(a0) 246; ZBA-NEXT: sd a4, 280(a0) 247; ZBA-NEXT: ret 248entry: 249 %add = add nsw i64 %a, 5 250 %cmp = icmp sgt i64 %x, 0 251 %spec.select = select i1 %cmp, i64 %add, i64 %b 252 %0 = getelementptr inbounds i64, ptr %array1, i64 %add 253 store i64 %spec.select, ptr %0 254 %add3 = add nsw i64 %a, 6 255 %arrayidx4 = getelementptr inbounds i64, ptr %array1, i64 %add3 256 store i64 %spec.select, ptr %arrayidx4 257 %add5 = add nsw i64 %a, 35 258 %arrayidx6 = getelementptr inbounds i64, ptr %array1, i64 %add5 259 store i64 %add, ptr %arrayidx6 260 ret void 261} 262 263define i64 @add_shl_moreOneUse_sh1add(i64 %x) { 264; NO-ZBA-LABEL: add_shl_moreOneUse_sh1add: 265; NO-ZBA: # %bb.0: 266; NO-ZBA-NEXT: ori a1, a0, 1 267; NO-ZBA-NEXT: slli a0, a0, 1 268; NO-ZBA-NEXT: ori a0, a0, 2 269; NO-ZBA-NEXT: add a0, a0, a1 270; NO-ZBA-NEXT: ret 271; 272; ZBA-LABEL: add_shl_moreOneUse_sh1add: 273; ZBA: # %bb.0: 274; ZBA-NEXT: ori a0, a0, 1 275; ZBA-NEXT: sh1add a0, a0, a0 276; ZBA-NEXT: ret 277 %or = or i64 %x, 1 278 %mul = shl i64 %or, 1 279 %add = add i64 %mul, %or 280 ret i64 %add 281} 282 283define i64 @add_shl_moreOneUse_sh2add(i64 %x) { 284; NO-ZBA-LABEL: add_shl_moreOneUse_sh2add: 285; NO-ZBA: # %bb.0: 286; NO-ZBA-NEXT: ori a1, a0, 1 287; NO-ZBA-NEXT: slli a0, a0, 2 288; NO-ZBA-NEXT: ori a0, a0, 4 289; NO-ZBA-NEXT: add a0, a0, a1 290; NO-ZBA-NEXT: ret 291; 292; ZBA-LABEL: add_shl_moreOneUse_sh2add: 293; ZBA: # %bb.0: 294; ZBA-NEXT: ori a0, a0, 1 295; ZBA-NEXT: sh2add a0, a0, a0 296; ZBA-NEXT: ret 297 %or = or i64 %x, 1 298 %mul = shl i64 %or, 2 299 %add = add i64 %mul, %or 300 ret i64 %add 301} 302 303define i64 @add_shl_moreOneUse_sh3add(i64 %x) { 304; NO-ZBA-LABEL: add_shl_moreOneUse_sh3add: 305; NO-ZBA: # %bb.0: 306; NO-ZBA-NEXT: ori a1, a0, 1 307; NO-ZBA-NEXT: slli a0, a0, 3 308; NO-ZBA-NEXT: ori a0, a0, 8 309; NO-ZBA-NEXT: add a0, a0, a1 310; NO-ZBA-NEXT: ret 311; 312; ZBA-LABEL: add_shl_moreOneUse_sh3add: 313; ZBA: # %bb.0: 314; ZBA-NEXT: ori a0, a0, 1 315; ZBA-NEXT: sh3add a0, a0, a0 316; ZBA-NEXT: ret 317 %or = or i64 %x, 1 318 %mul = shl i64 %or, 3 319 %add = add i64 %mul, %or 320 ret i64 %add 321} 322 323;; Covers a case which previously crashed (pr119527) 324define i64 @add_shl_sext(i32 %1) { 325; RV64-LABEL: add_shl_sext: 326; RV64: # %bb.0: 327; RV64-NEXT: addi a1, a0, 3 328; RV64-NEXT: sllw a0, a1, a0 329; RV64-NEXT: ret 330 %3 = add i32 %1, 3 331 %4 = shl i32 %3, %1 332 %5 = sext i32 %4 to i64 333 ret i64 %5 334} 335 336define i64 @add_shl_moreOneUse_sh4add(i64 %x) { 337; RV64-LABEL: add_shl_moreOneUse_sh4add: 338; RV64: # %bb.0: 339; RV64-NEXT: ori a1, a0, 1 340; RV64-NEXT: slli a0, a0, 4 341; RV64-NEXT: ori a0, a0, 16 342; RV64-NEXT: add a0, a0, a1 343; RV64-NEXT: ret 344 %or = or i64 %x, 1 345 %mul = shl i64 %or, 4 346 %add = add i64 %mul, %or 347 ret i64 %add 348} 349 350define i64 @add_shl_rhs_constant(i64 %x, i64 %y) { 351; RV64-LABEL: add_shl_rhs_constant: 352; RV64: # %bb.0: 353; RV64-NEXT: add a0, a0, a1 354; RV64-NEXT: slli a0, a0, 3 355; RV64-NEXT: ret 356 %a = add i64 %x, 1 357 %b = add i64 %y, %a 358 %c = shl i64 %b, 3 359 %d = add i64 %c, -8 360 ret i64 %d 361} 362