diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -478,6 +478,9 @@ bool isIntDivCheap(EVT VT, AttributeList Attr) const override; + bool canMergeStoresTo(unsigned AddressSpace, EVT MemVT, + const MachineFunction &MF) const override; + bool preferScalarizeSplat(SDNode *N) const override; bool softPromoteHalfType() const override { return true; } diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -17576,6 +17576,17 @@ return OptSize && !VT.isVector(); } +bool RISCVTargetLowering::canMergeStoresTo(unsigned AddressSpace, EVT MemVT, + const MachineFunction &MF) const { + // Do not merge to greater than XLen if no implicit float attribute is set. + + bool NoFloat = MF.getFunction().hasFnAttribute(Attribute::NoImplicitFloat); + + if (NoFloat) + return (MemVT.getSizeInBits() <= Subtarget.getXLen()); + return true; +} + bool RISCVTargetLowering::preferScalarizeSplat(SDNode *N) const { // Scalarize zero_ext and sign_ext might stop match to widening instruction in // some situation. diff --git a/llvm/test/CodeGen/RISCV/rvv/combine-store.ll b/llvm/test/CodeGen/RISCV/rvv/combine-store.ll --- a/llvm/test/CodeGen/RISCV/rvv/combine-store.ll +++ b/llvm/test/CodeGen/RISCV/rvv/combine-store.ll @@ -28,6 +28,21 @@ ret void } +define void @combine_zero_stores_4xi8_noimplicitfloat(ptr %p) noimplicitfloat { +; CHECK-LABEL: combine_zero_stores_4xi8_noimplicitfloat: +; CHECK: # %bb.0: +; CHECK-NEXT: sw zero, 0(a0) +; CHECK-NEXT: ret + store i8 zeroinitializer, ptr %p, align 4 + %gep1 = getelementptr i8, ptr %p, i64 1 + store i8 zeroinitializer, ptr %gep1 + %gep2 = getelementptr i8, ptr %p, i64 2 + store i8 zeroinitializer, ptr %gep2 + %gep3 = getelementptr i8, ptr %p, i64 3 + store i8 zeroinitializer, ptr %gep3 + ret void +} + define void @combine_zero_stores_8xi8(ptr %p) { ; RV32-LABEL: combine_zero_stores_8xi8: ; RV32: # %bb.0: @@ -68,6 +83,35 @@ ret void } +define void @combine_zero_stores_8xi8_noimplicitfloat(ptr %p) noimplicitfloat { +; RV32-LABEL: combine_zero_stores_8xi8_noimplicitfloat: +; RV32: # %bb.0: +; RV32-NEXT: sw zero, 0(a0) +; RV32-NEXT: sw zero, 4(a0) +; RV32-NEXT: ret +; +; RV64-LABEL: combine_zero_stores_8xi8_noimplicitfloat: +; RV64: # %bb.0: +; RV64-NEXT: sd zero, 0(a0) +; RV64-NEXT: ret + store i8 zeroinitializer, ptr %p, align 8 + %gep1 = getelementptr i8, ptr %p, i64 1 + store i8 zeroinitializer, ptr %gep1 + %gep2 = getelementptr i8, ptr %p, i64 2 + store i8 zeroinitializer, ptr %gep2 + %gep3 = getelementptr i8, ptr %p, i64 3 + store i8 zeroinitializer, ptr %gep3 + %gep4 = getelementptr i8, ptr %p, i64 4 + store i8 zeroinitializer, ptr %gep4, align 8 + %gep5 = getelementptr i8, ptr %p, i64 5 + store i8 zeroinitializer, ptr %gep5 + %gep6 = getelementptr i8, ptr %p, i64 6 + store i8 zeroinitializer, ptr %gep6 + %gep7 = getelementptr i8, ptr %p, i64 7 + store i8 zeroinitializer, ptr %gep7 + ret void +} + define void @combine_zero_stores_4xi16(ptr %p) { ; RV32-LABEL: combine_zero_stores_4xi16: ; RV32: # %bb.0: @@ -163,6 +207,30 @@ ret void } +define void @combine_zero_stores_4xi32_noimplicitfloat(ptr %p) noimplicitfloat { +; RV32-LABEL: combine_zero_stores_4xi32_noimplicitfloat: +; RV32: # %bb.0: +; RV32-NEXT: sw zero, 0(a0) +; RV32-NEXT: sw zero, 4(a0) +; RV32-NEXT: sw zero, 8(a0) +; RV32-NEXT: sw zero, 12(a0) +; RV32-NEXT: ret +; +; RV64-LABEL: combine_zero_stores_4xi32_noimplicitfloat: +; RV64: # %bb.0: +; RV64-NEXT: sd zero, 0(a0) +; RV64-NEXT: sd zero, 8(a0) +; RV64-NEXT: ret + store i32 zeroinitializer, ptr %p, align 16 + %gep1 = getelementptr i32, ptr %p, i64 1 + store i32 zeroinitializer, ptr %gep1 + %gep2 = getelementptr i32, ptr %p, i64 2 + store i32 zeroinitializer, ptr %gep2, align 8 + %gep3 = getelementptr i32, ptr %p, i64 3 + store i32 zeroinitializer, ptr %gep3 + ret void +} + define void @combine_zero_stores_8xi32(ptr %p) { ; RV32-LABEL: combine_zero_stores_8xi32: ; RV32: # %bb.0: