[llvm-branch-commits] [openmp] release/18.x: [OpenMP] fix endianness dependent definitions in OMP headers for MSVC (#84540) (PR #84668)
https://github.com/xingxue-ibm approved this pull request. Yes, it will be great if this patch can be picked up by v18.x. The OpenMP runtime libomp won't build without the fix if the build compiler is MSVC. https://github.com/llvm/llvm-project/pull/84668 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm][lld][RISCV] Support x3_reg_usage (PR #84598)
@@ -1136,11 +1136,35 @@ static void mergeAtomic(DenseMap &intAttr, }; } +static void mergeX3RegUse(DenseMap &intAttr, + const InputSectionBase *oldSection, + const InputSectionBase *newSection, + unsigned int oldTag, unsigned int newTag) { + // X3/GP register usage ar incompatible and cannot be merged, with the + // exception of the UNKNOWN or 0 value + using RISCVAttrs::RISCVX3RegUse::X3RegUsage; + auto attr = RISCVAttrs::X3_REG_USAGE; + if (newTag == X3RegUsage::UNKNOWN) +return; + if (oldTag == X3RegUsage::UNKNOWN) { +intAttr[attr] = newTag; topperc wrote: Can we use the iterator from try_emplace instead of a second map lookup? https://github.com/llvm/llvm-project/pull/84598 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/18.x: [X86] combineAndShuffleNot - ensure the type is legal before create X86ISD::ANDNP target nodes (PR #84698)
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/84698 Backport 862c7e0218f27b55a5b75ae59a4f73cd4610448d Requested by: @DianQK >From 4e1ce0cbafa9e2b4f7cb11249898a877deab48b4 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sun, 10 Mar 2024 16:23:51 + Subject: [PATCH] [X86] combineAndShuffleNot - ensure the type is legal before create X86ISD::ANDNP target nodes Fixes #84660 (cherry picked from commit 862c7e0218f27b55a5b75ae59a4f73cd4610448d) --- llvm/lib/Target/X86/X86ISelLowering.cpp | 11 +-- llvm/test/CodeGen/X86/combine-and.ll| 19 +++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a071c5a3ca0326..9e64726fb6fff7 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -47878,6 +47878,7 @@ static SDValue combineAndShuffleNot(SDNode *N, SelectionDAG &DAG, SDValue X, Y; SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); if (SDValue Not = GetNot(N0)) { X = Not; @@ -47891,9 +47892,11 @@ static SDValue combineAndShuffleNot(SDNode *N, SelectionDAG &DAG, X = DAG.getBitcast(VT, X); Y = DAG.getBitcast(VT, Y); SDLoc DL(N); + // We do not split for SSE at all, but we need to split vectors for AVX1 and // AVX2. - if (!Subtarget.useAVX512Regs() && VT.is512BitVector()) { + if (!Subtarget.useAVX512Regs() && VT.is512BitVector() && + TLI.isTypeLegal(VT.getHalfNumVectorElementsVT(*DAG.getContext( { SDValue LoX, HiX; std::tie(LoX, HiX) = splitVector(X, DAG, DL); SDValue LoY, HiY; @@ -47903,7 +47906,11 @@ static SDValue combineAndShuffleNot(SDNode *N, SelectionDAG &DAG, SDValue HiV = DAG.getNode(X86ISD::ANDNP, DL, SplitVT, {HiX, HiY}); return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, {LoV, HiV}); } - return DAG.getNode(X86ISD::ANDNP, DL, VT, {X, Y}); + + if (TLI.isTypeLegal(VT)) +return DAG.getNode(X86ISD::ANDNP, DL, VT, {X, Y}); + + return SDValue(); } // Try to widen AND, OR and XOR nodes to VT in order to remove casts around diff --git a/llvm/test/CodeGen/X86/combine-and.ll b/llvm/test/CodeGen/X86/combine-and.ll index d223b75419ac47..294fcd6a9563eb 100644 --- a/llvm/test/CodeGen/X86/combine-and.ll +++ b/llvm/test/CodeGen/X86/combine-and.ll @@ -1171,6 +1171,25 @@ define <4 x i32> @neg_scalar_broadcast_two_uses(i32 %a0, <4 x i32> %a1, ptr %a2) ret <4 x i32> %4 } +; PR84660 - check for illegal types +define <2 x i128> @neg_scalar_broadcast_illegaltype(i128 %arg) { +; CHECK-LABEL: neg_scalar_broadcast_illegaltype: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:notl %esi +; CHECK-NEXT:andl $1, %esi +; CHECK-NEXT:movq %rsi, 16(%rdi) +; CHECK-NEXT:movq %rsi, (%rdi) +; CHECK-NEXT:movq $0, 24(%rdi) +; CHECK-NEXT:movq $0, 8(%rdi) +; CHECK-NEXT:retq + %i = xor i128 %arg, 1 + %i1 = insertelement <2 x i128> zeroinitializer, i128 %i, i64 0 + %i2 = shufflevector <2 x i128> %i1, <2 x i128> zeroinitializer, <2 x i32> zeroinitializer + %i3 = and <2 x i128> , %i2 + ret <2 x i128> %i3 +} + define <2 x i64> @andnp_xx(<2 x i64> %v0) nounwind { ; SSE-LABEL: andnp_xx: ; SSE: # %bb.0: ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/18.x: [X86] combineAndShuffleNot - ensure the type is legal before create X86ISD::ANDNP target nodes (PR #84698)
https://github.com/llvmbot milestoned https://github.com/llvm/llvm-project/pull/84698 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/18.x: [X86] combineAndShuffleNot - ensure the type is legal before create X86ISD::ANDNP target nodes (PR #84698)
llvmbot wrote: @llvm/pr-subscribers-backend-x86 Author: None (llvmbot) Changes Backport 862c7e0218f27b55a5b75ae59a4f73cd4610448d Requested by: @DianQK --- Full diff: https://github.com/llvm/llvm-project/pull/84698.diff 2 Files Affected: - (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+9-2) - (modified) llvm/test/CodeGen/X86/combine-and.ll (+19) ``diff diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a071c5a3ca0326..9e64726fb6fff7 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -47878,6 +47878,7 @@ static SDValue combineAndShuffleNot(SDNode *N, SelectionDAG &DAG, SDValue X, Y; SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); if (SDValue Not = GetNot(N0)) { X = Not; @@ -47891,9 +47892,11 @@ static SDValue combineAndShuffleNot(SDNode *N, SelectionDAG &DAG, X = DAG.getBitcast(VT, X); Y = DAG.getBitcast(VT, Y); SDLoc DL(N); + // We do not split for SSE at all, but we need to split vectors for AVX1 and // AVX2. - if (!Subtarget.useAVX512Regs() && VT.is512BitVector()) { + if (!Subtarget.useAVX512Regs() && VT.is512BitVector() && + TLI.isTypeLegal(VT.getHalfNumVectorElementsVT(*DAG.getContext( { SDValue LoX, HiX; std::tie(LoX, HiX) = splitVector(X, DAG, DL); SDValue LoY, HiY; @@ -47903,7 +47906,11 @@ static SDValue combineAndShuffleNot(SDNode *N, SelectionDAG &DAG, SDValue HiV = DAG.getNode(X86ISD::ANDNP, DL, SplitVT, {HiX, HiY}); return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, {LoV, HiV}); } - return DAG.getNode(X86ISD::ANDNP, DL, VT, {X, Y}); + + if (TLI.isTypeLegal(VT)) +return DAG.getNode(X86ISD::ANDNP, DL, VT, {X, Y}); + + return SDValue(); } // Try to widen AND, OR and XOR nodes to VT in order to remove casts around diff --git a/llvm/test/CodeGen/X86/combine-and.ll b/llvm/test/CodeGen/X86/combine-and.ll index d223b75419ac47..294fcd6a9563eb 100644 --- a/llvm/test/CodeGen/X86/combine-and.ll +++ b/llvm/test/CodeGen/X86/combine-and.ll @@ -1171,6 +1171,25 @@ define <4 x i32> @neg_scalar_broadcast_two_uses(i32 %a0, <4 x i32> %a1, ptr %a2) ret <4 x i32> %4 } +; PR84660 - check for illegal types +define <2 x i128> @neg_scalar_broadcast_illegaltype(i128 %arg) { +; CHECK-LABEL: neg_scalar_broadcast_illegaltype: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:notl %esi +; CHECK-NEXT:andl $1, %esi +; CHECK-NEXT:movq %rsi, 16(%rdi) +; CHECK-NEXT:movq %rsi, (%rdi) +; CHECK-NEXT:movq $0, 24(%rdi) +; CHECK-NEXT:movq $0, 8(%rdi) +; CHECK-NEXT:retq + %i = xor i128 %arg, 1 + %i1 = insertelement <2 x i128> zeroinitializer, i128 %i, i64 0 + %i2 = shufflevector <2 x i128> %i1, <2 x i128> zeroinitializer, <2 x i32> zeroinitializer + %i3 = and <2 x i128> , %i2 + ret <2 x i128> %i3 +} + define <2 x i64> @andnp_xx(<2 x i64> %v0) nounwind { ; SSE-LABEL: andnp_xx: ; SSE: # %bb.0: `` https://github.com/llvm/llvm-project/pull/84698 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/18.x: [llvm][LoongArch] Improve loongarch_lasx_xvpermi_q instrinsic (#82984) (PR #83540)
https://github.com/SixWeining closed https://github.com/llvm/llvm-project/pull/83540 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/18.x: [llvm][LoongArch] Improve loongarch_lasx_xvpermi_q instrinsic (#82984) (PR #83540)
SixWeining wrote: > For the record, based on the principle of "explicit is better than implicit" > that generally holds, I'd favor an approach where such > compile-time-verifiable out-of-range operands are given compile-time errors, > or we should just pass through the value unmodified. Otherwise the intrinsic > would have to carry the workaround effectively forever, and we could find > ourselves trapped if later micro-architectures actually start to make use of > the currently cleared bits. Makes sense. After discussion with gcc-loongarch team, we both decide to revert this change. Thanks. https://github.com/llvm/llvm-project/pull/83540 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] c8a9929 - Revert "[llvm][LoongArch] Improve loongarch_lasx_xvpermi_q instrinsic (#82984)"
Author: Lu Weining Date: 2024-03-11T10:31:16+08:00 New Revision: c8a99293cb41576acb1cdd6e90ff2a04059b0075 URL: https://github.com/llvm/llvm-project/commit/c8a99293cb41576acb1cdd6e90ff2a04059b0075 DIFF: https://github.com/llvm/llvm-project/commit/c8a99293cb41576acb1cdd6e90ff2a04059b0075.diff LOG: Revert "[llvm][LoongArch] Improve loongarch_lasx_xvpermi_q instrinsic (#82984)" This reverts commit d7c80bba698bded48c1df4b4bb7424a181aa6195. Added: Modified: llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll Removed: diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 2d71423d6dd593..907aae13d6de0c 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -968,28 +968,6 @@ static SDValue checkIntrinsicImmArg(SDValue Op, unsigned ImmOp, return SDValue(); } -static SDValue checkAndModifyXVPERMI_QIntrinsicImmArg(SDValue Op, - SelectionDAG &DAG) { - SDValue Op3 = Op->getOperand(3); - uint64_t Imm = Op3->getAsZExtVal(); - // Check the range of ImmArg. - if (!isUInt<8>(Imm)) { -DAG.getContext()->emitError(Op->getOperationName(0) + -": argument out of range."); -return DAG.getNode(ISD::UNDEF, SDLoc(Op), Op.getValueType()); - } - - // For instruction xvpermi.q, only [1:0] and [5:4] bits of operands[3] - // are used. The unused bits in operands[3] need to be set to 0 to avoid - // causing undefined behavior on LA464. - if ((Imm & 0x33) != Imm) { -Op3 = DAG.getTargetConstant(Imm & 0x33, SDLoc(Op), Op3.getValueType()); -DAG.UpdateNodeOperands(Op.getNode(), Op->getOperand(0), Op->getOperand(1), - Op->getOperand(2), Op3); - } - return SDValue(); -} - SDValue LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { @@ -1247,14 +1225,13 @@ LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::loongarch_lsx_vextrins_d: case Intrinsic::loongarch_lasx_xvshuf4i_d: case Intrinsic::loongarch_lasx_xvpermi_w: + case Intrinsic::loongarch_lasx_xvpermi_q: case Intrinsic::loongarch_lasx_xvbitseli_b: case Intrinsic::loongarch_lasx_xvextrins_b: case Intrinsic::loongarch_lasx_xvextrins_h: case Intrinsic::loongarch_lasx_xvextrins_w: case Intrinsic::loongarch_lasx_xvextrins_d: return checkIntrinsicImmArg<8>(Op, 3, DAG); - case Intrinsic::loongarch_lasx_xvpermi_q: -return checkAndModifyXVPERMI_QIntrinsicImmArg(Op, DAG); case Intrinsic::loongarch_lsx_vrepli_b: case Intrinsic::loongarch_lsx_vrepli_h: case Intrinsic::loongarch_lsx_vrepli_w: diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll index 92669d2e589558..0d9f9daabc4488 100644 --- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll +++ b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll @@ -36,33 +36,3 @@ entry: %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 1) ret <32 x i8> %res } - -define <32 x i8> @lasx_xvpermi_q_204(<32 x i8> %va, <32 x i8> %vb) nounwind { -; CHECK-LABEL: lasx_xvpermi_q_204: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT:xvpermi.q $xr0, $xr1, 0 -; CHECK-NEXT:ret -entry: - %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 204) - ret <32 x i8> %res -} - -define <32 x i8> @lasx_xvpermi_q_221(<32 x i8> %va, <32 x i8> %vb) nounwind { -; CHECK-LABEL: lasx_xvpermi_q_221: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT:xvpermi.q $xr0, $xr1, 17 -; CHECK-NEXT:ret -entry: - %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 221) - ret <32 x i8> %res -} - -define <32 x i8> @lasx_xvpermi_q_255(<32 x i8> %va, <32 x i8> %vb) nounwind { -; CHECK-LABEL: lasx_xvpermi_q_255: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT:xvpermi.q $xr0, $xr1, 51 -; CHECK-NEXT:ret -entry: - %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 255) - ret <32 x i8> %res -} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/18.x: [Clang][LoongArch] Fix wrong return value type of __iocsrrd_h (#84100) (PR #84715)
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/84715 Backport aeda1a6e800e 2f479b811274 Requested by: @SixWeining >From a31f312f41f39aa6894ebcb23837dc76b052f6ad Mon Sep 17 00:00:00 2001 From: wanglei Date: Tue, 5 Mar 2024 19:44:28 +0800 Subject: [PATCH 1/2] [Clang][LoongArch] Precommit test for fix wrong return value type of __iocsrrd_h. NFC (cherry picked from commit aeda1a6e800e0dd6c91c0332b4db95094ad5b301) --- clang/test/CodeGen/LoongArch/intrinsic-la32.c | 29 ++- clang/test/CodeGen/LoongArch/intrinsic-la64.c | 21 -- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la32.c b/clang/test/CodeGen/LoongArch/intrinsic-la32.c index 93d54f511a9cd2..6a8d99880be399 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la32.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la32.c @@ -169,8 +169,8 @@ unsigned int cpucfg(unsigned int a) { // LA32-LABEL: @rdtime( // LA32-NEXT: entry: -// LA32-NEXT:[[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 -// LA32-NEXT:[[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 +// LA32-NEXT:[[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc [[META2:![0-9]+]] +// LA32-NEXT:[[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc [[META3:![0-9]+]] // LA32-NEXT:ret void // void rdtime() { @@ -201,13 +201,28 @@ void loongarch_movgr2fcsr(int a) { __builtin_loongarch_movgr2fcsr(1, a); } -// CHECK-LABEL: @cacop_w( -// CHECK-NEXT: entry: -// CHECK-NEXT:tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A:%.*]], i32 1024) -// CHECK-NEXT:tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A]], i32 1024) -// CHECK-NEXT:ret void +// LA32-LABEL: @cacop_w( +// LA32-NEXT: entry: +// LA32-NEXT:tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A:%.*]], i32 1024) +// LA32-NEXT:tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A]], i32 1024) +// LA32-NEXT:ret void // void cacop_w(unsigned long int a) { __cacop_w(1, a, 1024); __builtin_loongarch_cacop_w(1, a, 1024); } + +// LA32-LABEL: @iocsrrd_h_result( +// LA32-NEXT: entry: +// LA32-NEXT:[[TMP0:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A:%.*]]) +// LA32-NEXT:[[TMP1:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A]]) +// LA32-NEXT:[[CONV2:%.*]] = and i32 [[TMP0]], 255 +// LA32-NEXT:[[ADD:%.*]] = add i32 [[TMP1]], [[CONV2]] +// LA32-NEXT:[[CONV4:%.*]] = trunc i32 [[ADD]] to i16 +// LA32-NEXT:ret i16 [[CONV4]] +// +unsigned short iocsrrd_h_result(unsigned int a) { + unsigned short b = __iocsrrd_h(a); + unsigned short c = __builtin_loongarch_iocsrrd_h(a); + return b+c; +} diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la64.c b/clang/test/CodeGen/LoongArch/intrinsic-la64.c index a740882eef5411..48b6a7a3d22704 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c @@ -387,7 +387,7 @@ unsigned int cpucfg(unsigned int a) { // CHECK-LABEL: @rdtime_d( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call { i64, i64 } asm sideeffect "rdtime.d $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK-NEXT:[[TMP0:%.*]] = tail call { i64, i64 } asm sideeffect "rdtime.d $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc [[META2:![0-9]+]] // CHECK-NEXT:ret void // void rdtime_d() { @@ -396,8 +396,8 @@ void rdtime_d() { // CHECK-LABEL: @rdtime( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 -// CHECK-NEXT:[[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !4 +// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc [[META3:![0-9]+]] +// CHECK-NEXT:[[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc [[META4:![0-9]+]] // CHECK-NEXT:ret void // void rdtime() { @@ -427,3 +427,18 @@ void loongarch_movgr2fcsr(int a) { __movgr2fcsr(1, a); __builtin_loongarch_movgr2fcsr(1, a); } + +// CHECK-LABEL: @iocsrrd_h_result( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[TMP0:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A:%.*]]) +// CHECK-NEXT:[[TMP1:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A]]) +// CHECK-NEXT:[[CONV2:%.*]] = and i32 [[TMP0]], 255 +// CHECK-NEXT:[[ADD:%.*]] = add i32 [[TMP1]], [[CONV2]] +// CHECK-NEXT:[[CONV4:%.*]] = trunc i32 [[ADD]] to i16 +// CHECK-NEXT:ret i16 [[CONV4]] +// +unsigned short iocsrrd_h
[llvm-branch-commits] [clang] release/18.x: [Clang][LoongArch] Fix wrong return value type of __iocsrrd_h (#84100) (PR #84715)
https://github.com/llvmbot milestoned https://github.com/llvm/llvm-project/pull/84715 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/18.x: [Clang][LoongArch] Fix wrong return value type of __iocsrrd_h (#84100) (PR #84715)
llvmbot wrote: @SixWeining What do you think about merging this PR to the release branch? https://github.com/llvm/llvm-project/pull/84715 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/18.x: [LoongArch] Make sure that the LoongArchISD::BSTRINS node uses the correct `MSB` value (#84454) (PR #84716)
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/84716 Backport edd4c6c6dca4 Requested by: @SixWeining >From 2eb997da54bab3fcc90ec2c60e76972bb75f5c7e Mon Sep 17 00:00:00 2001 From: wanglei Date: Mon, 11 Mar 2024 08:59:17 +0800 Subject: [PATCH] [LoongArch] Make sure that the LoongArchISD::BSTRINS node uses the correct `MSB` value (#84454) The `MSB` must not be greater than `GRLen`. Without this patch, newly added test cases will crash with LoongArch32, resulting in a 'cannot select' error. (cherry picked from commit edd4c6c6dca4c556de22b2ab73d5bfc02d28e59b) --- llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp | 4 +++- llvm/test/CodeGen/LoongArch/bstrins_w.ll| 13 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 76c1a14fe0156c..821c16630b9158 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -2343,7 +2343,9 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG, return DAG.getNode( LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0), DAG.getConstant(CN1->getSExtValue() >> MaskIdx0, DL, ValTy), -DAG.getConstant((MaskIdx0 + MaskLen0 - 1), DL, GRLenVT), +DAG.getConstant(ValBits == 32 ? (MaskIdx0 + (MaskLen0 & 31) - 1) + : (MaskIdx0 + MaskLen0 - 1), +DL, GRLenVT), DAG.getConstant(MaskIdx0, DL, GRLenVT)); } diff --git a/llvm/test/CodeGen/LoongArch/bstrins_w.ll b/llvm/test/CodeGen/LoongArch/bstrins_w.ll index dfbe000841cdcb..e008caacad2a17 100644 --- a/llvm/test/CodeGen/LoongArch/bstrins_w.ll +++ b/llvm/test/CodeGen/LoongArch/bstrins_w.ll @@ -145,6 +145,19 @@ define i32 @pat5(i32 %a) nounwind { ret i32 %or } +;; The high bits of `const` are zero. +define i32 @pat5_high_zeros(i32 %a) nounwind { +; CHECK-LABEL: pat5_high_zeros: +; CHECK: # %bb.0: +; CHECK-NEXT:lu12i.w $a1, 1 +; CHECK-NEXT:ori $a1, $a1, 564 +; CHECK-NEXT:bstrins.w $a0, $a1, 31, 16 +; CHECK-NEXT:ret + %and = and i32 %a, 65535 ; 0x + %or = or i32 %and, 305397760 ; 0x1234 + ret i32 %or +} + ;; Pattern 6: a = b | ((c & mask) << shamt) ;; In this testcase b is 0x1002, but in fact we do not require b being a ;; constant. As long as all positions in b to be overwritten by the incoming ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/18.x: [LoongArch] Make sure that the LoongArchISD::BSTRINS node uses the correct `MSB` value (#84454) (PR #84716)
https://github.com/llvmbot milestoned https://github.com/llvm/llvm-project/pull/84716 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/18.x: [Clang][LoongArch] Fix wrong return value type of __iocsrrd_h (#84100) (PR #84715)
llvmbot wrote: @llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-clang Author: None (llvmbot) Changes Backport aeda1a6e800e 2f479b811274 Requested by: @SixWeining --- Full diff: https://github.com/llvm/llvm-project/pull/84715.diff 3 Files Affected: - (modified) clang/lib/Headers/larchintrin.h (+1-1) - (modified) clang/test/CodeGen/LoongArch/intrinsic-la32.c (+22-7) - (modified) clang/test/CodeGen/LoongArch/intrinsic-la64.c (+18-3) ``diff diff --git a/clang/lib/Headers/larchintrin.h b/clang/lib/Headers/larchintrin.h index a613e5ca0e5ecd..f4218295919a0d 100644 --- a/clang/lib/Headers/larchintrin.h +++ b/clang/lib/Headers/larchintrin.h @@ -156,7 +156,7 @@ extern __inline unsigned char return (unsigned char)__builtin_loongarch_iocsrrd_b((unsigned int)_1); } -extern __inline unsigned char +extern __inline unsigned short __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __iocsrrd_h(unsigned int _1) { return (unsigned short)__builtin_loongarch_iocsrrd_h((unsigned int)_1); diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la32.c b/clang/test/CodeGen/LoongArch/intrinsic-la32.c index 93d54f511a9cd2..eb3f8cbe7ac4cc 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la32.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la32.c @@ -169,8 +169,8 @@ unsigned int cpucfg(unsigned int a) { // LA32-LABEL: @rdtime( // LA32-NEXT: entry: -// LA32-NEXT:[[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 -// LA32-NEXT:[[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 +// LA32-NEXT:[[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc [[META2:![0-9]+]] +// LA32-NEXT:[[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc [[META3:![0-9]+]] // LA32-NEXT:ret void // void rdtime() { @@ -201,13 +201,28 @@ void loongarch_movgr2fcsr(int a) { __builtin_loongarch_movgr2fcsr(1, a); } -// CHECK-LABEL: @cacop_w( -// CHECK-NEXT: entry: -// CHECK-NEXT:tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A:%.*]], i32 1024) -// CHECK-NEXT:tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A]], i32 1024) -// CHECK-NEXT:ret void +// LA32-LABEL: @cacop_w( +// LA32-NEXT: entry: +// LA32-NEXT:tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A:%.*]], i32 1024) +// LA32-NEXT:tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A]], i32 1024) +// LA32-NEXT:ret void // void cacop_w(unsigned long int a) { __cacop_w(1, a, 1024); __builtin_loongarch_cacop_w(1, a, 1024); } + +// LA32-LABEL: @iocsrrd_h_result( +// LA32-NEXT: entry: +// LA32-NEXT:[[TMP0:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A:%.*]]) +// LA32-NEXT:[[CONV_I:%.*]] = trunc i32 [[TMP0]] to i16 +// LA32-NEXT:[[TMP1:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A]]) +// LA32-NEXT:[[TMP2:%.*]] = trunc i32 [[TMP1]] to i16 +// LA32-NEXT:[[CONV3:%.*]] = add i16 [[TMP2]], [[CONV_I]] +// LA32-NEXT:ret i16 [[CONV3]] +// +unsigned short iocsrrd_h_result(unsigned int a) { + unsigned short b = __iocsrrd_h(a); + unsigned short c = __builtin_loongarch_iocsrrd_h(a); + return b+c; +} diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la64.c b/clang/test/CodeGen/LoongArch/intrinsic-la64.c index a740882eef5411..50ec358f546ec0 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c @@ -387,7 +387,7 @@ unsigned int cpucfg(unsigned int a) { // CHECK-LABEL: @rdtime_d( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call { i64, i64 } asm sideeffect "rdtime.d $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK-NEXT:[[TMP0:%.*]] = tail call { i64, i64 } asm sideeffect "rdtime.d $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc [[META2:![0-9]+]] // CHECK-NEXT:ret void // void rdtime_d() { @@ -396,8 +396,8 @@ void rdtime_d() { // CHECK-LABEL: @rdtime( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 -// CHECK-NEXT:[[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !4 +// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc [[META3:![0-9]+]] +// CHECK-NEXT:[[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc [[META4:![0-9]+]] // CHECK-NEXT:ret void // void rdtime() { @@ -427,3 +427,18 @@ void loongarch_movgr2fcsr(int a) { __movgr2fcsr(1, a); __builtin_loongarch_movgr2fcsr(1, a); } + +// CHECK-LABEL: @iocsrrd_h_result( +// CHECK-NEXT: entry: +// CHECK-NE
[llvm-branch-commits] [llvm] release/18.x: [LoongArch] Make sure that the LoongArchISD::BSTRINS node uses the correct `MSB` value (#84454) (PR #84716)
llvmbot wrote: @heiher What do you think about merging this PR to the release branch? https://github.com/llvm/llvm-project/pull/84716 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/18.x: [LoongArch] Make sure that the LoongArchISD::BSTRINS node uses the correct `MSB` value (#84454) (PR #84716)
llvmbot wrote: @llvm/pr-subscribers-backend-loongarch Author: None (llvmbot) Changes Backport edd4c6c6dca4 Requested by: @SixWeining --- Full diff: https://github.com/llvm/llvm-project/pull/84716.diff 2 Files Affected: - (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+3-1) - (modified) llvm/test/CodeGen/LoongArch/bstrins_w.ll (+13) ``diff diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 76c1a14fe0156c..821c16630b9158 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -2343,7 +2343,9 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG, return DAG.getNode( LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0), DAG.getConstant(CN1->getSExtValue() >> MaskIdx0, DL, ValTy), -DAG.getConstant((MaskIdx0 + MaskLen0 - 1), DL, GRLenVT), +DAG.getConstant(ValBits == 32 ? (MaskIdx0 + (MaskLen0 & 31) - 1) + : (MaskIdx0 + MaskLen0 - 1), +DL, GRLenVT), DAG.getConstant(MaskIdx0, DL, GRLenVT)); } diff --git a/llvm/test/CodeGen/LoongArch/bstrins_w.ll b/llvm/test/CodeGen/LoongArch/bstrins_w.ll index dfbe000841cdcb..e008caacad2a17 100644 --- a/llvm/test/CodeGen/LoongArch/bstrins_w.ll +++ b/llvm/test/CodeGen/LoongArch/bstrins_w.ll @@ -145,6 +145,19 @@ define i32 @pat5(i32 %a) nounwind { ret i32 %or } +;; The high bits of `const` are zero. +define i32 @pat5_high_zeros(i32 %a) nounwind { +; CHECK-LABEL: pat5_high_zeros: +; CHECK: # %bb.0: +; CHECK-NEXT:lu12i.w $a1, 1 +; CHECK-NEXT:ori $a1, $a1, 564 +; CHECK-NEXT:bstrins.w $a0, $a1, 31, 16 +; CHECK-NEXT:ret + %and = and i32 %a, 65535 ; 0x + %or = or i32 %and, 305397760 ; 0x1234 + ret i32 %or +} + ;; Pattern 6: a = b | ((c & mask) << shamt) ;; In this testcase b is 0x1002, but in fact we do not require b being a ;; constant. As long as all positions in b to be overwritten by the incoming `` https://github.com/llvm/llvm-project/pull/84716 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm][lld][RISCV] Support x3_reg_usage (PR #84598)
@@ -24,6 +24,9 @@ .attribute priv_spec_revision, 0 # CHECK: attribute 12, 0 + wangpc-pp wrote: This blank should be added in Atomic ABI PR I think. https://github.com/llvm/llvm-project/pull/84598 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm][lld][RISCV] Support x3_reg_usage (PR #84598)
@@ -520,3 +520,8 @@ define i8 @atomic_load_i8_seq_cst(ptr %a) nounwind { ; A6S: .attribute 14, 2 ; A6C: .attribute 14, 1 } + wangpc-pp wrote: No CHECKs for this test or I miss something here? https://github.com/llvm/llvm-project/pull/84598 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm][lld][RISCV] Support x3_reg_usage (PR #84598)
@@ -47,6 +48,15 @@ enum AtomicABI : unsigned { }; } // namespace RISCVAtomicAbiTag +namespace RISCVX3RegUse { +enum X3RegUsage : unsigned { + UNKNOWN = 0, + GP = 0, wangpc-pp wrote: Copy paste mistakes? Why all 0s? https://github.com/llvm/llvm-project/pull/84598 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [RISCV][NFC] Pass LMUL to copyPhysRegVector (PR #84448)
https://github.com/wangpc-pp edited https://github.com/llvm/llvm-project/pull/84448 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][IR] Trigger `notifyOperationReplaced` on `replaceAllOpUsesWith` (PR #84721)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/84721 Before this change: `notifyOperationReplaced` was triggered when calling `RewriteBase::replaceOp`. After this change: `notifyOperationReplaced` is triggered when `RewriterBase::replaceAllOpUsesWith` or `RewriterBase::replaceOp` is called. Until now, every `notifyOperationReplaced` was always sent together with a `notifyOperationErased`, which made that `notifyOperationErased` callback irrelevant. More importantly, when a user called `RewriterBase::replaceAllOpUsesWith`+`RewriterBase::eraseOp` instead of `RewriterBase::replaceOp`, no `notifyOperationReplaced` callback was sent, even though the two notations are semantically equivalent. As an example, this can be a problem when applying patterns with the transform dialect because the `TrackingListener` will only see the `notifyOperationErased` callback and the payload op is dropped from the mappings. Note: It is still possible to write semantically equivalent code that does not trigger a `notifyOperationReplaced` (e.g., when op results are replaced one-by-one), but this commit already improves the situation a lot. >From 7b93ec38417a397c5fc6dba9ced4243c55204bfb Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Mon, 11 Mar 2024 05:16:10 + Subject: [PATCH] [mlir][IR] Trigger `notifyOperationReplaced` on `replaceAllOpUsesWith` Before this change: `notifyOperationReplaced` was triggered when calling `RewriteBase::replaceOp`. After this change: `notifyOperationReplaced` is triggered when `RewriterBase::replaceAllOpUsesWith` or `RewriterBase::replaceOp` is called. Until now, every `notifyOperationReplaced` was always sent together with a `notifyOperationErased`, which made that `notifyOperationErased` callback irrelevant. More importantly, when a user called `RewriterBase::replaceAllOpUsesWith`+`RewriterBase::eraseOp` instead of `RewriterBase::replaceOp`, no `notifyOperationReplaced` callback was sent, even though the two notations are semantically equivalent. As an example, this can be a problem when applying patterns with the transform dialect because the `TrackingListener` will only see the `notifyOperationErased` callback and the payload op is dropped from the mappings. Note: It is still possible to write semantically equivalent code that does not trigger a `notifyOperationReplaced` (e.g., when op results are replaced one-by-one), but this commit already improves the situation a lot. --- mlir/include/mlir/IR/PatternMatch.h | 29 - mlir/lib/IR/PatternMatch.cpp| 24 +++-- mlir/test/lib/Dialect/Test/TestPatterns.cpp | 5 +++- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index 8d84ab617e..c1408c3f90a53b 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -409,9 +409,9 @@ class RewriterBase : public OpBuilder { /// Notify the listener that the specified operation was modified in-place. virtual void notifyOperationModified(Operation *op) {} -/// Notify the listener that the specified operation is about to be replaced -/// with another operation. This is called before the uses of the old -/// operation have been changed. +/// Notify the listener that all uses of the specified operation's results +/// are about to be replaced with the results of another operation. This is +/// called before the uses of the old operation have been changed. /// /// By default, this function calls the "operation replaced with values" /// notification. @@ -420,9 +420,10 @@ class RewriterBase : public OpBuilder { notifyOperationReplaced(op, replacement->getResults()); } -/// Notify the listener that the specified operation is about to be replaced -/// with the a range of values, potentially produced by other operations. -/// This is called before the uses of the operation have been changed. +/// Notify the listener that all uses of the specified operation's results +/// are about to be replaced with the a range of values, potentially +/// produced by other operations. This is called before the uses of the +/// operation have been changed. virtual void notifyOperationReplaced(Operation *op, ValueRange replacement) {} @@ -628,12 +629,16 @@ class RewriterBase : public OpBuilder { for (auto it : llvm::zip(from, to)) replaceAllUsesWith(std::get<0>(it), std::get<1>(it)); } - // Note: This function cannot be called `replaceAllUsesWith` because the - // overload resolution, when called with an op that can be implicitly - // converted to a Value, would be ambiguous. - void replaceAllOpUsesWith(Operation *from, ValueRange to) { -replaceAllUsesWith(from->getResults(), to); - } + + /// Find uses of `from` a
[llvm-branch-commits] [mlir] [mlir][IR] Trigger `notifyOperationReplaced` on `replaceAllOpUsesWith` (PR #84721)
llvmbot wrote: @llvm/pr-subscribers-mlir Author: Matthias Springer (matthias-springer) Changes Before this change: `notifyOperationReplaced` was triggered when calling `RewriteBase::replaceOp`. After this change: `notifyOperationReplaced` is triggered when `RewriterBase::replaceAllOpUsesWith` or `RewriterBase::replaceOp` is called. Until now, every `notifyOperationReplaced` was always sent together with a `notifyOperationErased`, which made that `notifyOperationErased` callback irrelevant. More importantly, when a user called `RewriterBase::replaceAllOpUsesWith`+`RewriterBase::eraseOp` instead of `RewriterBase::replaceOp`, no `notifyOperationReplaced` callback was sent, even though the two notations are semantically equivalent. As an example, this can be a problem when applying patterns with the transform dialect because the `TrackingListener` will only see the `notifyOperationErased` callback and the payload op is dropped from the mappings. Note: It is still possible to write semantically equivalent code that does not trigger a `notifyOperationReplaced` (e.g., when op results are replaced one-by-one), but this commit already improves the situation a lot. --- Full diff: https://github.com/llvm/llvm-project/pull/84721.diff 3 Files Affected: - (modified) mlir/include/mlir/IR/PatternMatch.h (+17-12) - (modified) mlir/lib/IR/PatternMatch.cpp (+16-8) - (modified) mlir/test/lib/Dialect/Test/TestPatterns.cpp (+4-1) ``diff diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index 8d84ab617e..c1408c3f90a53b 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -409,9 +409,9 @@ class RewriterBase : public OpBuilder { /// Notify the listener that the specified operation was modified in-place. virtual void notifyOperationModified(Operation *op) {} -/// Notify the listener that the specified operation is about to be replaced -/// with another operation. This is called before the uses of the old -/// operation have been changed. +/// Notify the listener that all uses of the specified operation's results +/// are about to be replaced with the results of another operation. This is +/// called before the uses of the old operation have been changed. /// /// By default, this function calls the "operation replaced with values" /// notification. @@ -420,9 +420,10 @@ class RewriterBase : public OpBuilder { notifyOperationReplaced(op, replacement->getResults()); } -/// Notify the listener that the specified operation is about to be replaced -/// with the a range of values, potentially produced by other operations. -/// This is called before the uses of the operation have been changed. +/// Notify the listener that all uses of the specified operation's results +/// are about to be replaced with the a range of values, potentially +/// produced by other operations. This is called before the uses of the +/// operation have been changed. virtual void notifyOperationReplaced(Operation *op, ValueRange replacement) {} @@ -628,12 +629,16 @@ class RewriterBase : public OpBuilder { for (auto it : llvm::zip(from, to)) replaceAllUsesWith(std::get<0>(it), std::get<1>(it)); } - // Note: This function cannot be called `replaceAllUsesWith` because the - // overload resolution, when called with an op that can be implicitly - // converted to a Value, would be ambiguous. - void replaceAllOpUsesWith(Operation *from, ValueRange to) { -replaceAllUsesWith(from->getResults(), to); - } + + /// Find uses of `from` and replace them with `to`. Also notify the listener + /// about every in-place op modification (for every use that was replaced) + /// and that the `from` operation is about to be replaced. + /// + /// Note: This function cannot be called `replaceAllUsesWith` because the + /// overload resolution, when called with an op that can be implicitly + /// converted to a Value, would be ambiguous. + void replaceAllOpUsesWith(Operation *from, ValueRange to); + void replaceAllOpUsesWith(Operation *from, Operation *to); /// Find uses of `from` and replace them with `to` if the `functor` returns /// true. Also notify the listener about every in-place op modification (for diff --git a/mlir/lib/IR/PatternMatch.cpp b/mlir/lib/IR/PatternMatch.cpp index 4079ccc7567256..5944a0ea46a143 100644 --- a/mlir/lib/IR/PatternMatch.cpp +++ b/mlir/lib/IR/PatternMatch.cpp @@ -110,6 +110,22 @@ RewriterBase::~RewriterBase() { // Out of line to provide a vtable anchor for the class. } +void RewriterBase::replaceAllOpUsesWith(Operation *from, ValueRange to) { + // Notify the listener that we're about to replace this op. + if (auto *rewriteListener = dyn_cast_if_present(listener)) +rewriteListener->notifyOperationReplaced(from, to); + + replaceAllUsesWith(from->getRe
[llvm-branch-commits] [mlir] [mlir][IR][NFC] Make `replaceAllUsesWith` non-templatized (PR #84722)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/84722 Turn `RewriterBase::replaceAllUsesWith` into a non-templatized implementation, so that it can be made virtual and be overridden in the `ConversionPatternRewriter` in a subsequent change. This change is in preparation of adding dialect conversion support for `replaceAllUsesWith`. >From e70c754e4a0f9b16fa6588e2d398dcaf0e7e995f Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Mon, 11 Mar 2024 05:22:26 + Subject: [PATCH] [mlir][IR][NFC] Make `replaceAllUsesWith` non-templatized Turn `RewriterBase::replaceAllUsesWith` into a non-templatized implementation, so that it can be made virtual and be overridden in the `ConversionPatternRewriter` in a subsequent change. This change is in preparation of adding dialect conversion support for `replaceAllUsesWith`. --- mlir/include/mlir/IR/PatternMatch.h | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index c1408c3f90a53b..2be1e2e2b40276 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -615,11 +615,13 @@ class RewriterBase : public OpBuilder { /// Find uses of `from` and replace them with `to`. Also notify the listener /// about every in-place op modification (for every use that was replaced). void replaceAllUsesWith(Value from, Value to) { -return replaceAllUsesWith(from.getImpl(), to); +for (OpOperand &operand : llvm::make_early_inc_range(from.getUses())) { + Operation *op = operand.getOwner(); + modifyOpInPlace(op, [&]() { operand.set(to); }); +} } - template - void replaceAllUsesWith(IRObjectWithUseList *from, ValueT &&to) { -for (OperandType &operand : llvm::make_early_inc_range(from->getUses())) { + void replaceAllUsesWith(Block *from, Block *to) { +for (BlockOperand &operand : llvm::make_early_inc_range(from->getUses())) { Operation *op = operand.getOwner(); modifyOpInPlace(op, [&]() { operand.set(to); }); } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][IR][NFC] Make `replaceAllUsesWith` non-templatized (PR #84722)
llvmbot wrote: @llvm/pr-subscribers-mlir-core Author: Matthias Springer (matthias-springer) Changes Turn `RewriterBase::replaceAllUsesWith` into a non-templatized implementation, so that it can be made virtual and be overridden in the `ConversionPatternRewriter` in a subsequent change. This change is in preparation of adding dialect conversion support for `replaceAllUsesWith`. --- Full diff: https://github.com/llvm/llvm-project/pull/84722.diff 1 Files Affected: - (modified) mlir/include/mlir/IR/PatternMatch.h (+6-4) ``diff diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index c1408c3f90a53b..2be1e2e2b40276 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -615,11 +615,13 @@ class RewriterBase : public OpBuilder { /// Find uses of `from` and replace them with `to`. Also notify the listener /// about every in-place op modification (for every use that was replaced). void replaceAllUsesWith(Value from, Value to) { -return replaceAllUsesWith(from.getImpl(), to); +for (OpOperand &operand : llvm::make_early_inc_range(from.getUses())) { + Operation *op = operand.getOwner(); + modifyOpInPlace(op, [&]() { operand.set(to); }); +} } - template - void replaceAllUsesWith(IRObjectWithUseList *from, ValueT &&to) { -for (OperandType &operand : llvm::make_early_inc_range(from->getUses())) { + void replaceAllUsesWith(Block *from, Block *to) { +for (BlockOperand &operand : llvm::make_early_inc_range(from->getUses())) { Operation *op = operand.getOwner(); modifyOpInPlace(op, [&]() { operand.set(to); }); } `` https://github.com/llvm/llvm-project/pull/84722 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/18.x: backport [C++20] [Moduls] Avoid computing odr hash for functions from comparing constraint expression (PR #84723)
https://github.com/ChuanqiXu9 milestoned https://github.com/llvm/llvm-project/pull/84723 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/18.x: backport [C++20] [Moduls] Avoid computing odr hash for functions from comparing constraint expression (PR #84723)
https://github.com/ChuanqiXu9 created https://github.com/llvm/llvm-project/pull/84723 Backport 3f6bc1adf805681293c2ef0b93b708ff52244c00 This fixes a surprising regression introduced in https://github.com/llvm/llvm-project/issues/79240. Given we've backported that to 18.x. We need to backport this fix to 18.x too. >From 9139ca67d7afc1838562ea73d14d693c59c929ff Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Mon, 11 Mar 2024 11:14:40 +0800 Subject: [PATCH] [C++20] [Moduls] Avoid computing odr hash for functions from comparing constraint expression Previously we disabled to compute ODR hash for declarations from the global module fragment. However, we missed the case that the functions lives in the concept requiments (see the attached the test files for example). And the mismatch causes the potential crashment. Due to we will set the function body as lazy after we deserialize it and we will only take its body when needed. However, we don't allow to take the body during deserializing. So it is actually potentially problematic if we set the body as lazy first and computing the hash value of the function, which requires to deserialize its body. So we will meet a crash here. This patch tries to solve the issue by not taking the body of the function from GMF. Note that we can't skip comparing the constraint expression from the GMF directly since it is an key part of the function selecting and it may be the reason why we can't return 0 directly for `FunctionDecl::getODRHash()` from the GMF. --- clang/include/clang/AST/DeclBase.h| 10 +++ clang/include/clang/Serialization/ASTReader.h | 7 -- clang/lib/AST/Decl.cpp| 2 +- clang/lib/AST/DeclBase.cpp| 5 ++ clang/lib/Serialization/ASTReader.cpp | 2 +- clang/lib/Serialization/ASTReaderDecl.cpp | 8 +-- clang/lib/Serialization/ASTWriter.cpp | 2 +- clang/lib/Serialization/ASTWriterDecl.cpp | 8 +-- .../hashing-decls-in-exprs-from-gmf.cppm | 67 +++ 9 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 clang/test/Modules/hashing-decls-in-exprs-from-gmf.cppm diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 9a4736019d1b1b..eb7a1a32060077 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -673,6 +673,16 @@ class alignas(8) Decl { /// fragment. See [module.global.frag]p3,4 for details. bool isDiscardedInGlobalModuleFragment() const { return false; } + /// Check if we should skip checking ODRHash for declaration \param D. + /// + /// The existing ODRHash mechanism seems to be not stable enough and + /// the false positive ODR violation reports are annoying and we rarely see + /// true ODR violation reports. Also we learned that MSVC disabled ODR checks + /// for declarations in GMF. So we try to disable ODR checks in the GMF to + /// get better user experiences before we make the ODR violation checks stable + /// enough. + bool shouldSkipCheckingODR() const; + /// Return true if this declaration has an attribute which acts as /// definition of the entity, such as 'alias' or 'ifunc'. bool hasDefiningAttr() const; diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index cd28226c295b32..62c25f5b7a0df8 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -2451,13 +2451,6 @@ class BitsUnpacker { uint32_t Value; uint32_t CurrentBitsIndex = ~0; }; - -inline bool shouldSkipCheckingODR(const Decl *D) { - return D->getOwningModule() && - D->getASTContext().getLangOpts().SkipODRCheckInGMF && - D->getOwningModule()->isExplicitGlobalModule(); -} - } // namespace clang #endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 26fdfa040796ed..1ee33fd7576d7d 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -4476,7 +4476,7 @@ unsigned FunctionDecl::getODRHash() { } class ODRHash Hash; - Hash.AddFunctionDecl(this); + Hash.AddFunctionDecl(this, /*SkipBody=*/shouldSkipCheckingODR()); setHasODRHash(true); ODRHash = Hash.CalculateHash(); return ODRHash; diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 8163f9bdaf8d97..6b3c13ff206d23 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1102,6 +1102,11 @@ bool Decl::isInAnotherModuleUnit() const { return M != getASTContext().getCurrentNamedModule(); } +bool Decl::shouldSkipCheckingODR() const { + return getASTContext().getLangOpts().SkipODRCheckInGMF && getOwningModule() && + getOwningModule()->isExplicitGlobalModule(); +} + static Decl::Kind getKind(const Decl *D) { return D->getKind(); } static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); } diff --git a/clang/lib/Serializati
[llvm-branch-commits] [clang] release/18.x: backport [C++20] [Moduls] Avoid computing odr hash for functions from comparing constraint expression (PR #84723)
llvmbot wrote: @llvm/pr-subscribers-clang-modules Author: Chuanqi Xu (ChuanqiXu9) Changes Backport 3f6bc1adf805681293c2ef0b93b708ff52244c00 This fixes a surprising regression introduced in https://github.com/llvm/llvm-project/issues/79240. Given we've backported that to 18.x. We need to backport this fix to 18.x too. --- Full diff: https://github.com/llvm/llvm-project/pull/84723.diff 9 Files Affected: - (modified) clang/include/clang/AST/DeclBase.h (+10) - (modified) clang/include/clang/Serialization/ASTReader.h (-7) - (modified) clang/lib/AST/Decl.cpp (+1-1) - (modified) clang/lib/AST/DeclBase.cpp (+5) - (modified) clang/lib/Serialization/ASTReader.cpp (+1-1) - (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+4-4) - (modified) clang/lib/Serialization/ASTWriter.cpp (+1-1) - (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+4-4) - (added) clang/test/Modules/hashing-decls-in-exprs-from-gmf.cppm (+67) ``diff diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 9a4736019d1b1b..eb7a1a32060077 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -673,6 +673,16 @@ class alignas(8) Decl { /// fragment. See [module.global.frag]p3,4 for details. bool isDiscardedInGlobalModuleFragment() const { return false; } + /// Check if we should skip checking ODRHash for declaration \param D. + /// + /// The existing ODRHash mechanism seems to be not stable enough and + /// the false positive ODR violation reports are annoying and we rarely see + /// true ODR violation reports. Also we learned that MSVC disabled ODR checks + /// for declarations in GMF. So we try to disable ODR checks in the GMF to + /// get better user experiences before we make the ODR violation checks stable + /// enough. + bool shouldSkipCheckingODR() const; + /// Return true if this declaration has an attribute which acts as /// definition of the entity, such as 'alias' or 'ifunc'. bool hasDefiningAttr() const; diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index cd28226c295b32..62c25f5b7a0df8 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -2451,13 +2451,6 @@ class BitsUnpacker { uint32_t Value; uint32_t CurrentBitsIndex = ~0; }; - -inline bool shouldSkipCheckingODR(const Decl *D) { - return D->getOwningModule() && - D->getASTContext().getLangOpts().SkipODRCheckInGMF && - D->getOwningModule()->isExplicitGlobalModule(); -} - } // namespace clang #endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 26fdfa040796ed..1ee33fd7576d7d 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -4476,7 +4476,7 @@ unsigned FunctionDecl::getODRHash() { } class ODRHash Hash; - Hash.AddFunctionDecl(this); + Hash.AddFunctionDecl(this, /*SkipBody=*/shouldSkipCheckingODR()); setHasODRHash(true); ODRHash = Hash.CalculateHash(); return ODRHash; diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 8163f9bdaf8d97..6b3c13ff206d23 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1102,6 +1102,11 @@ bool Decl::isInAnotherModuleUnit() const { return M != getASTContext().getCurrentNamedModule(); } +bool Decl::shouldSkipCheckingODR() const { + return getASTContext().getLangOpts().SkipODRCheckInGMF && getOwningModule() && + getOwningModule()->isExplicitGlobalModule(); +} + static Decl::Kind getKind(const Decl *D) { return D->getKind(); } static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 028610deb3001e..490b8cb10a4841 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -9745,7 +9745,7 @@ void ASTReader::finishPendingActions() { !NonConstDefn->isLateTemplateParsed() && // We only perform ODR checks for decls not in the explicit // global module fragment. -!shouldSkipCheckingODR(FD) && +!FD->shouldSkipCheckingODR() && FD->getODRHash() != NonConstDefn->getODRHash()) { if (!isa(FD)) { PendingFunctionOdrMergeFailures[FD].push_back(NonConstDefn); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 321c11e55c14e3..110f55f8c0f49a 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -832,7 +832,7 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { Reader.mergeDefinitionVisibility(OldDef, ED); // We don't want to check the ODR hash value for declarations from global // module fragment. - if (!shouldSkipCheckingODR(ED) && + if (!ED->sh
[llvm-branch-commits] [llvm] release/18.x: [LoongArch] Make sure that the LoongArchISD::BSTRINS node uses the correct `MSB` value (#84454) (PR #84716)
https://github.com/heiher approved this pull request. LGTM. https://github.com/llvm/llvm-project/pull/84716 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits