Index: llvm/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -637,6 +637,11 @@ return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); }]>; +def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, + GISDNodeXFormEquiv; +def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, + GISDNodeXFormEquiv; + let DiagnosticType = "LogicalSecondSource" in { def LogicalImm32Operand : AsmOperandClass { let Name = "LogicalImm32"; Index: llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -210,6 +210,8 @@ unsigned SizeInBytes) const; void renderTruncImm(MachineInstrBuilder &MIB, const MachineInstr &MI) const; + void renderLogicalImm32(MachineInstrBuilder &MIB, const MachineInstr &I) const; + void renderLogicalImm64(MachineInstrBuilder &MIB, const MachineInstr &I) const; // Materialize a GlobalValue or BlockAddress using a movz+movk sequence. void materializeLargeCMVal(MachineInstr &I, const Value *V, @@ -4493,6 +4495,22 @@ MIB.addImm(CstVal.getValue()); } +void AArch64InstructionSelector::renderLogicalImm32( + MachineInstrBuilder &MIB, const MachineInstr &I) const { + assert(I.getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT"); + uint64_t CstVal = I.getOperand(1).getCImm()->getZExtValue(); + uint64_t Enc = AArch64_AM::encodeLogicalImmediate(CstVal, 32); + MIB.addImm(Enc); +} + +void AArch64InstructionSelector::renderLogicalImm64( + MachineInstrBuilder &MIB, const MachineInstr &I) const { + assert(I.getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT"); + uint64_t CstVal = I.getOperand(1).getCImm()->getZExtValue(); + uint64_t Enc = AArch64_AM::encodeLogicalImmediate(CstVal, 64); + MIB.addImm(Enc); +} + namespace llvm { InstructionSelector * createAArch64InstructionSelector(const AArch64TargetMachine &TM, Index: llvm/test/CodeGen/AArch64/GlobalISel/select-logical-imm.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/GlobalISel/select-logical-imm.mir @@ -0,0 +1,123 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=aarch64-unknown-unknown -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s + +--- +name: logical_imm_64_and +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: name: logical_imm_64_and + ; CHECK: liveins: $x0 + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK: [[ANDXri:%[0-9]+]]:gpr64sp = ANDXri [[COPY]], 4096 + ; CHECK: $x0 = COPY [[ANDXri]] + ; CHECK: RET_ReallyLR implicit $x0 + %0:gpr(s64) = COPY $x0 + %1:gpr(s64) = G_CONSTANT i64 1 + %2:gpr(s64) = G_AND %0, %1:gpr(s64) + $x0 = COPY %2:gpr(s64) + RET_ReallyLR implicit $x0 +... +--- +name: logical_imm_64_or +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: name: logical_imm_64_or + ; CHECK: liveins: $x0 + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK: [[ORRXri:%[0-9]+]]:gpr64sp = ORRXri [[COPY]], 4096 + ; CHECK: $x0 = COPY [[ORRXri]] + ; CHECK: RET_ReallyLR implicit $x0 + %0:gpr(s64) = COPY $x0 + %1:gpr(s64) = G_CONSTANT i64 1 + %2:gpr(s64) = G_OR %0, %1:gpr(s64) + $x0 = COPY %2:gpr(s64) + RET_ReallyLR implicit $x0 +... +--- +name: logical_imm_64_xor +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: name: logical_imm_64_xor + ; CHECK: liveins: $x0 + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK: [[EORXri:%[0-9]+]]:gpr64sp = EORXri [[COPY]], 4096 + ; CHECK: $x0 = COPY [[EORXri]] + ; CHECK: RET_ReallyLR implicit $x0 + %0:gpr(s64) = COPY $x0 + %1:gpr(s64) = G_CONSTANT i64 1 + %2:gpr(s64) = G_XOR %0, %1:gpr(s64) + $x0 = COPY %2:gpr(s64) + RET_ReallyLR implicit $x0 +... +--- +name: logical_imm_32_and +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0 + ; CHECK-LABEL: name: logical_imm_32_and + ; CHECK: liveins: $w0 + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 + ; CHECK: [[ANDWri:%[0-9]+]]:gpr32sp = ANDWri [[COPY]], 0 + ; CHECK: $w0 = COPY [[ANDWri]] + ; CHECK: RET_ReallyLR implicit $w0 + %0:gpr(s32) = COPY $w0 + %1:gpr(s32) = G_CONSTANT i32 1 + %2:gpr(s32) = G_AND %0, %1:gpr(s32) + $w0 = COPY %2:gpr(s32) + RET_ReallyLR implicit $w0 +... +--- +name: logical_imm_32_or +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0 + ; CHECK-LABEL: name: logical_imm_32_or + ; CHECK: liveins: $w0 + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 + ; CHECK: [[ORRWri:%[0-9]+]]:gpr32sp = ORRWri [[COPY]], 0 + ; CHECK: $w0 = COPY [[ORRWri]] + ; CHECK: RET_ReallyLR implicit $w0 + %0:gpr(s32) = COPY $w0 + %1:gpr(s32) = G_CONSTANT i32 1 + %2:gpr(s32) = G_OR %0, %1:gpr(s32) + $w0 = COPY %2:gpr(s32) + RET_ReallyLR implicit $w0 +... +--- +name: logical_imm_32_xor +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0 + ; CHECK-LABEL: name: logical_imm_32_xor + ; CHECK: liveins: $w0 + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 + ; CHECK: [[EORWri:%[0-9]+]]:gpr32sp = EORWri [[COPY]], 0 + ; CHECK: $w0 = COPY [[EORWri]] + ; CHECK: RET_ReallyLR implicit $w0 + %0:gpr(s32) = COPY $w0 + %1:gpr(s32) = G_CONSTANT i32 1 + %2:gpr(s32) = G_XOR %0, %1:gpr(s32) + $w0 = COPY %2:gpr(s32) + RET_ReallyLR implicit $w0 +... Index: llvm/test/CodeGen/AArch64/GlobalISel/select-pr32733.mir =================================================================== --- llvm/test/CodeGen/AArch64/GlobalISel/select-pr32733.mir +++ llvm/test/CodeGen/AArch64/GlobalISel/select-pr32733.mir @@ -53,10 +53,10 @@ liveins: $w0 ; CHECK-LABEL: name: main ; CHECK: liveins: $w0 - ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 - ; CHECK: [[EONWrr:%[0-9]+]]:gpr32 = EONWrr [[COPY]], [[MOVi32imm]] - ; CHECK: $w0 = COPY [[EONWrr]] + ; CHECK: [[ORNWrr:%[0-9]+]]:gpr32 = ORNWrr $wzr, [[COPY]] + ; CHECK: [[EORWri:%[0-9]+]]:gpr32sp = EORWri [[ORNWrr]], 0 + ; CHECK: $w0 = COPY [[EORWri]] %0(s32) = G_CONSTANT i32 -1 %3(s32) = G_CONSTANT i32 1 %1(s32) = COPY $w0 Index: llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-shift-imm.mir =================================================================== --- llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-shift-imm.mir +++ llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-shift-imm.mir @@ -131,8 +131,8 @@ ; CHECK-LABEL: name: lshr_32_notimm64 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 8 - ; CHECK: [[ANDXrr:%[0-9]+]]:gpr64 = ANDXrr [[MOVi64imm]], [[MOVi64imm]] - ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY [[ANDXrr]].sub_32 + ; CHECK: [[ANDXri:%[0-9]+]]:gpr64sp = ANDXri [[MOVi64imm]], 8000 + ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY [[ANDXri]].sub_32 ; CHECK: [[LSRVWr:%[0-9]+]]:gpr32 = LSRVWr [[COPY]], [[COPY1]] ; CHECK: $w0 = COPY [[LSRVWr]] ; CHECK: RET_ReallyLR implicit $w0 @@ -155,8 +155,8 @@ ; CHECK-LABEL: name: ashr_32_notimm64 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 8 - ; CHECK: [[ANDXrr:%[0-9]+]]:gpr64 = ANDXrr [[MOVi64imm]], [[MOVi64imm]] - ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY [[ANDXrr]].sub_32 + ; CHECK: [[ANDXri:%[0-9]+]]:gpr64sp = ANDXri [[MOVi64imm]], 8000 + ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY [[ANDXri]].sub_32 ; CHECK: [[ASRVWr:%[0-9]+]]:gpr32 = ASRVWr [[COPY]], [[COPY1]] ; CHECK: $w0 = COPY [[ASRVWr]] ; CHECK: RET_ReallyLR implicit $w0