SixWeining created this revision. SixWeining added reviewers: xen0n, xry111, MaskRay, wangleiat, gonglingqin. Herald added subscribers: StephenFan, hiraditya. Herald added a project: All. SixWeining requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
'J' is defined in GCC [1] but not documented [2] while Linux [3] has already used it in LoongArch port. [1]: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/constraints.md#L61 [2]: https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html [3]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/asm/cmpxchg.h#L19 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D136835 Files: clang/lib/Basic/Targets/LoongArch.cpp clang/test/CodeGen/LoongArch/inline-asm-constraints.c llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll Index: llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll =================================================================== --- llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll +++ llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll @@ -58,6 +58,17 @@ ret void } +define void @constraint_J() nounwind { +; CHECK-LABEL: constraint_J: +; CHECK: # %bb.0: +; CHECK-NEXT: #APP +; CHECK-NEXT: addi.w $a0, $a0, 0 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: ret + tail call void asm sideeffect "addi.w $$a0, $$a0, $0", "J"(i32 0) + ret void +} + define void @constraint_K() nounwind { ; CHECK-LABEL: constraint_K: ; CHECK: # %bb.0: Index: llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll =================================================================== --- llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll +++ llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll @@ -17,6 +17,12 @@ ret void } +define void @constraint_J() { +; CHECK: error: value out of range for constraint 'J' + tail call void asm sideeffect "addi.w $$a0, $$a0, $$0", "J"(i32 1) + ret void +} + define void @constraint_K() { ; CHECK: error: value out of range for constraint 'K' tail call void asm sideeffect "andi.w $$a0, $$a0, $0", "K"(i32 4096) Index: llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp =================================================================== --- llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -2169,6 +2169,7 @@ return C_RegisterClass; case 'l': case 'I': + case 'J': case 'K': return C_Immediate; case 'k': @@ -2272,6 +2273,13 @@ DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT())); } return; + case 'J': + // Validate & create an integer zero operand. + if (auto *C = dyn_cast<ConstantSDNode>(Op)) + if (C->getZExtValue() == 0) + Ops.push_back( + DAG.getTargetConstant(0, SDLoc(Op), Subtarget.getGRLenVT())); + return; case 'K': // Validate & create a 12-bit unsigned immediate operand. if (auto *C = dyn_cast<ConstantSDNode>(Op)) { Index: clang/test/CodeGen/LoongArch/inline-asm-constraints.c =================================================================== --- clang/test/CodeGen/LoongArch/inline-asm-constraints.c +++ clang/test/CodeGen/LoongArch/inline-asm-constraints.c @@ -43,6 +43,12 @@ asm volatile ("" :: "I"(-2048)); } +void test_J(void) { +// CHECK-LABEL: define{{.*}} void @test_J() +// CHECK: call void asm sideeffect "", "J"(i32 0) + asm volatile ("" :: "J"(0)); +} + void test_K(void) { // CHECK-LABEL: define{{.*}} void @test_K() // CHECK: call void asm sideeffect "", "K"(i32 4095) Index: clang/lib/Basic/Targets/LoongArch.cpp =================================================================== --- clang/lib/Basic/Targets/LoongArch.cpp +++ clang/lib/Basic/Targets/LoongArch.cpp @@ -88,6 +88,10 @@ // A signed 12-bit constant (for arithmetic instructions). Info.setRequiresImmediate(-2048, 2047); return true; + case 'J': + // Integer zero. + Info.setRequiresImmediate(0); + return true; case 'K': // An unsigned 12-bit constant (for logic instructions). Info.setRequiresImmediate(0, 4095);
Index: llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll =================================================================== --- llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll +++ llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll @@ -58,6 +58,17 @@ ret void } +define void @constraint_J() nounwind { +; CHECK-LABEL: constraint_J: +; CHECK: # %bb.0: +; CHECK-NEXT: #APP +; CHECK-NEXT: addi.w $a0, $a0, 0 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: ret + tail call void asm sideeffect "addi.w $$a0, $$a0, $0", "J"(i32 0) + ret void +} + define void @constraint_K() nounwind { ; CHECK-LABEL: constraint_K: ; CHECK: # %bb.0: Index: llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll =================================================================== --- llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll +++ llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll @@ -17,6 +17,12 @@ ret void } +define void @constraint_J() { +; CHECK: error: value out of range for constraint 'J' + tail call void asm sideeffect "addi.w $$a0, $$a0, $$0", "J"(i32 1) + ret void +} + define void @constraint_K() { ; CHECK: error: value out of range for constraint 'K' tail call void asm sideeffect "andi.w $$a0, $$a0, $0", "K"(i32 4096) Index: llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp =================================================================== --- llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -2169,6 +2169,7 @@ return C_RegisterClass; case 'l': case 'I': + case 'J': case 'K': return C_Immediate; case 'k': @@ -2272,6 +2273,13 @@ DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT())); } return; + case 'J': + // Validate & create an integer zero operand. + if (auto *C = dyn_cast<ConstantSDNode>(Op)) + if (C->getZExtValue() == 0) + Ops.push_back( + DAG.getTargetConstant(0, SDLoc(Op), Subtarget.getGRLenVT())); + return; case 'K': // Validate & create a 12-bit unsigned immediate operand. if (auto *C = dyn_cast<ConstantSDNode>(Op)) { Index: clang/test/CodeGen/LoongArch/inline-asm-constraints.c =================================================================== --- clang/test/CodeGen/LoongArch/inline-asm-constraints.c +++ clang/test/CodeGen/LoongArch/inline-asm-constraints.c @@ -43,6 +43,12 @@ asm volatile ("" :: "I"(-2048)); } +void test_J(void) { +// CHECK-LABEL: define{{.*}} void @test_J() +// CHECK: call void asm sideeffect "", "J"(i32 0) + asm volatile ("" :: "J"(0)); +} + void test_K(void) { // CHECK-LABEL: define{{.*}} void @test_K() // CHECK: call void asm sideeffect "", "K"(i32 4095) Index: clang/lib/Basic/Targets/LoongArch.cpp =================================================================== --- clang/lib/Basic/Targets/LoongArch.cpp +++ clang/lib/Basic/Targets/LoongArch.cpp @@ -88,6 +88,10 @@ // A signed 12-bit constant (for arithmetic instructions). Info.setRequiresImmediate(-2048, 2047); return true; + case 'J': + // Integer zero. + Info.setRequiresImmediate(0); + return true; case 'K': // An unsigned 12-bit constant (for logic instructions). Info.setRequiresImmediate(0, 4095);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits