diff options
author | Alex Richardson <alexrichardson@google.com> | 2025-06-11 16:51:27 -0700 |
---|---|---|
committer | Alex Richardson <alexrichardson@google.com> | 2025-06-11 16:51:27 -0700 |
commit | 18c2f3b974c1f094c99d7f8db4d2ed398a9a8cf1 (patch) | |
tree | cc1245b1f76f561da83a95bccdb0aaa26832f700 | |
parent | c2f0af514beb7618660cf8d145fa9e49fb78869c (diff) | |
download | llvm-users/arichardson/spr/main.giselvaluetracking-correctly-truncatezext-g_ptrtoaddr.zip llvm-users/arichardson/spr/main.giselvaluetracking-correctly-truncatezext-g_ptrtoaddr.tar.gz llvm-users/arichardson/spr/main.giselvaluetracking-correctly-truncatezext-g_ptrtoaddr.tar.bz2 |
[𝘀𝗽𝗿] changes to main this commit is based onusers/arichardson/spr/main.giselvaluetracking-correctly-truncatezext-g_ptrtoaddr
Created using spr 1.3.6-beta.1
[skip ci]
47 files changed, 903 insertions, 85 deletions
diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst index a39994c..add4a89 100644 --- a/llvm/docs/GlobalISel/GenericOpcode.rst +++ b/llvm/docs/GlobalISel/GenericOpcode.rst @@ -169,6 +169,15 @@ Convert a pointer to an integer. %1:_(s32) = G_PTRTOINT %0:_(p0) +G_PTRTOADDR +^^^^^^^^^^^ + +Extract the address part of a pointer to an integer. + +.. code-block:: none + + %1:_(s32) = G_PTRTOADDR %0:_(p0) + G_BITCAST ^^^^^^^^^ diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index cc72a37..06c8b6e 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -12466,6 +12466,61 @@ Example: %Y = ptrtoint ptr %P to i64 ; yields zero extension on 32-bit architecture %Z = ptrtoint <4 x ptr> %P to <4 x i64>; yields vector zero extension for a vector of addresses on 32-bit architecture +.. _i_ptrtoaddr: + +'``ptrtoaddr .. to``' Instruction +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +:: + + <result> = ptrtoaddr <ty> <value> to <ty2> ; yields ty2 + +Overview: +""""""""" + +The '``ptrtoaddr``' instruction converts the pointer or a vector of +pointers ``value`` to the underlying integer address (or vector of integers) of +type ``ty2``. This is different from :ref:`ptrtoint <i_ptrtoint>` in that it +only operates on the index bits of the pointer and ignores all other bits. + +Arguments: +"""""""""" + +The '``ptrtoaddr``' instruction takes a ``value`` to cast, which must be +a value of type :ref:`pointer <t_pointer>` or a vector of pointers, and a +type to cast it to ``ty2``, which must be an :ref:`integer <t_integer>` or +a vector of integers type. + +Semantics: +"""""""""" + +The '``ptrtoaddr``' instruction converts ``value`` to integer type +``ty2`` by interpreting the lowest index-width pointer representation bits as an +integer and either truncating or zero extending that value to the size of the +integer type. +If the address of ``value`` is smaller than ``ty2`` then a zero extension is +done. If the address of ``value`` is larger than ``ty2`` then a truncation is +done. If the address size and the pointer representation size are the same and +``value`` and ``ty2`` are the same size, then nothing is done (*no-op cast*) +other than a type change. + +The ``ptrtoaddr`` always :ref:`captures the address (but not provenance) <pointercapture>` +of the pointer argument. + +Example: +"""""""" +This example assumes pointers in address space 1 are 64 bits in size with an +address width of 32 bits (``p1:64:64:64:32`` :ref:`datalayout string<langref_datalayout>`) +.. code-block:: llvm + + %X = ptrtoaddr ptr addrspace(1) %P to i8 ; extracts low 32 bits and truncates + %Y = ptrtoaddr ptr addrspace(1) %P to i64 ; extracts low 32 bits and zero extends + %Z = ptrtoaddr <4 x ptr addrspace(1)> %P to <4 x i64>; yields vector zero extension of low 32 bits for each pointer + + .. _i_inttoptr: '``inttoptr .. to``' Instruction diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 6857944..dd74c68 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -110,6 +110,7 @@ typedef enum { LLVMFPTrunc = 37, LLVMFPExt = 38, LLVMPtrToInt = 39, + LLVMPtrToAddr = 69, LLVMIntToPtr = 40, LLVMBitCast = 41, LLVMAddrSpaceCast = 60, diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h index a80b4c5..55228884 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -732,6 +732,12 @@ public: return 0; break; } + case Instruction::PtrToAddr: { + unsigned DstSize = Dst->getScalarSizeInBits(); + if (DL.isLegalInteger(DstSize) && DstSize >= DL.getAddressSizeInBits(Src)) + return 0; + break; + } case Instruction::PtrToInt: { unsigned DstSize = Dst->getScalarSizeInBits(); if (DL.isLegalInteger(DstSize) && @@ -1438,6 +1444,7 @@ public: Op2Info, Operands, I); } case Instruction::IntToPtr: + case Instruction::PtrToAddr: case Instruction::PtrToInt: case Instruction::SIToFP: case Instruction::UIToFP: diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h index c7e4bdf..13ff9e7 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -318,6 +318,7 @@ enum Kind { kw_fptoui, kw_fptosi, kw_inttoptr, + kw_ptrtoaddr, kw_ptrtoint, kw_bitcast, kw_addrspacecast, diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index b362a88..e00c9ee 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -456,7 +456,8 @@ enum CastOpcodes { CAST_PTRTOINT = 9, CAST_INTTOPTR = 10, CAST_BITCAST = 11, - CAST_ADDRSPACECAST = 12 + CAST_ADDRSPACECAST = 12, + CAST_PTRTOADDR = 13, }; /// UnaryOpcodes - These are values used in the bitcode files to encode which diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h index 571ec6d..c9bb04f 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h @@ -870,6 +870,7 @@ public: case TargetOpcode::G_FPTOUI_SAT: case TargetOpcode::G_FPTRUNC: case TargetOpcode::G_INTTOPTR: + case TargetOpcode::G_PTRTOADDR: case TargetOpcode::G_PTRTOINT: case TargetOpcode::G_SEXT: case TargetOpcode::G_SITOFP: diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 6fd05c8..3f465b8 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -486,6 +486,9 @@ private: bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) { return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder); } + bool translatePtrToAddr(const User &U, MachineIRBuilder &MIRBuilder) { + return translateCast(TargetOpcode::G_PTRTOADDR, U, MIRBuilder); + } bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) { return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder); } diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h index 4106be4..cfd7b10 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h @@ -429,6 +429,7 @@ public: LLVM_ABI LegalizeResult lowerFunnelShift(MachineInstr &MI); LLVM_ABI LegalizeResult lowerEXT(MachineInstr &MI); LLVM_ABI LegalizeResult lowerTRUNC(MachineInstr &MI); + LLVM_ABI LegalizeResult lowerPTRTOADDR(MachineInstr &MI); LLVM_ABI LegalizeResult lowerRotateWithReverseRotate(MachineInstr &MI); LLVM_ABI LegalizeResult lowerRotate(MachineInstr &MI); diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 25fef99..d60ba10 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -715,6 +715,11 @@ public: return buildInstr(TargetOpcode::G_PTRTOINT, {Dst}, {Src}); } + /// Build and insert a G_PTRTOADDR instruction. + MachineInstrBuilder buildPtrToAddr(const DstOp &Dst, const SrcOp &Src) { + return buildInstr(TargetOpcode::G_PTRTOADDR, {Dst}, {Src}); + } + /// Build and insert a G_INTTOPTR instruction. MachineInstrBuilder buildIntToPtr(const DstOp &Dst, const SrcOp &Src) { return buildInstr(TargetOpcode::G_INTTOPTR, {Dst}, {Src}); diff --git a/llvm/include/llvm/IR/InstVisitor.h b/llvm/include/llvm/IR/InstVisitor.h index b4eb729..04d7b80 100644 --- a/llvm/include/llvm/IR/InstVisitor.h +++ b/llvm/include/llvm/IR/InstVisitor.h @@ -183,6 +183,7 @@ public: RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst);} RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst);} RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);} + RetTy visitPtrToAddrInst(PtrToAddrInst &I) { DELEGATE(CastInst);} RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);} RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);} RetTy visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst);} diff --git a/llvm/include/llvm/IR/Instruction.def b/llvm/include/llvm/IR/Instruction.def index a5ad92f..face6a9 100644 --- a/llvm/include/llvm/IR/Instruction.def +++ b/llvm/include/llvm/IR/Instruction.def @@ -190,35 +190,36 @@ HANDLE_CAST_INST(43, UIToFP , UIToFPInst ) // UInt -> floating point HANDLE_CAST_INST(44, SIToFP , SIToFPInst ) // SInt -> floating point HANDLE_CAST_INST(45, FPTrunc , FPTruncInst ) // Truncate floating point HANDLE_CAST_INST(46, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(47, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(48, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(49, BitCast , BitCastInst ) // Type cast -HANDLE_CAST_INST(50, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast - LAST_CAST_INST(50) +HANDLE_CAST_INST(47, PtrToInt, PtrToIntInst) // Pointer -> Integer (bitcast) +HANDLE_CAST_INST(48, PtrToAddr, PtrToAddrInst) // Pointer -> Address +HANDLE_CAST_INST(49, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(50, BitCast , BitCastInst ) // Type cast +HANDLE_CAST_INST(51, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast + LAST_CAST_INST(51) - FIRST_FUNCLETPAD_INST(51) -HANDLE_FUNCLETPAD_INST(51, CleanupPad, CleanupPadInst) -HANDLE_FUNCLETPAD_INST(52, CatchPad , CatchPadInst) - LAST_FUNCLETPAD_INST(52) + FIRST_FUNCLETPAD_INST(52) +HANDLE_FUNCLETPAD_INST(52, CleanupPad, CleanupPadInst) +HANDLE_FUNCLETPAD_INST(53, CatchPad , CatchPadInst) + LAST_FUNCLETPAD_INST(53) // Other operators... - FIRST_OTHER_INST(53) -HANDLE_OTHER_INST(53, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(54, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(55, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(56, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(57, Select , SelectInst ) // select instruction -HANDLE_USER_INST (58, UserOp1, Instruction) // May be used internally in a pass -HANDLE_USER_INST (59, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(60, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(61, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(62, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(63, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(64, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(65, InsertValue, InsertValueInst) // insert into aggregate -HANDLE_OTHER_INST(66, LandingPad, LandingPadInst) // Landing pad instruction. -HANDLE_OTHER_INST(67, Freeze, FreezeInst) // Freeze instruction. - LAST_OTHER_INST(67) + FIRST_OTHER_INST(54) +HANDLE_OTHER_INST(54, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(55, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(56, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(57, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(58, Select , SelectInst ) // select instruction +HANDLE_USER_INST (59, UserOp1, Instruction) // May be used internally in a pass +HANDLE_USER_INST (60, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(61, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(62, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(63, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(64, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(65, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(66, InsertValue, InsertValueInst) // insert into aggregate +HANDLE_OTHER_INST(67, LandingPad, LandingPadInst) // Landing pad instruction. +HANDLE_OTHER_INST(68, Freeze, FreezeInst) // Freeze instruction. + LAST_OTHER_INST(68) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index 6f69b68..adb9324 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -4949,6 +4949,46 @@ public: } }; +/// This class represents a cast from a pointer to an address (non-capturing +/// ptrtoint). +class PtrToAddrInst : public CastInst { +protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + + /// Clone an identical PtrToIntInst. + PtrToAddrInst *cloneImpl() const; + +public: + /// Constructor with insert-before-instruction semantics + PtrToAddrInst(Value *S, ///< The value to be converted + Type *Ty, ///< The type to convert to + const Twine &NameStr = "", ///< A name for the new instruction + InsertPosition InsertBefore = + nullptr ///< Where to insert the new instruction + ); + + /// Gets the pointer operand. + Value *getPointerOperand() { return getOperand(0); } + /// Gets the pointer operand. + const Value *getPointerOperand() const { return getOperand(0); } + /// Gets the operand index of the pointer operand. + static unsigned getPointerOperandIndex() { return 0U; } + + /// Returns the address space of the pointer operand. + unsigned getPointerAddressSpace() const { + return getPointerOperand()->getType()->getPointerAddressSpace(); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const Instruction *I) { + return I->getOpcode() == PtrToAddr; + } + static bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + //===----------------------------------------------------------------------===// // BitCastInst Class //===----------------------------------------------------------------------===// diff --git a/llvm/include/llvm/SandboxIR/Instruction.h b/llvm/include/llvm/SandboxIR/Instruction.h index 4e3ff19..df1d6f8 100644 --- a/llvm/include/llvm/SandboxIR/Instruction.h +++ b/llvm/include/llvm/SandboxIR/Instruction.h @@ -2278,6 +2278,7 @@ class CastInst : public UnaryInstruction { return Opcode::FPToSI; case llvm::Instruction::FPExt: return Opcode::FPExt; + case llvm::Instruction::PtrToAddr: case llvm::Instruction::PtrToInt: return Opcode::PtrToInt; case llvm::Instruction::IntToPtr: diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def index 92fd60e..cbcf0b2 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -343,6 +343,9 @@ HANDLE_TARGET_OPCODE(G_CONCAT_VECTORS) /// Generic pointer to int conversion. HANDLE_TARGET_OPCODE(G_PTRTOINT) +/// Generic pointer to address conversion. +HANDLE_TARGET_OPCODE(G_PTRTOADDR) + /// Generic int to pointer conversion. HANDLE_TARGET_OPCODE(G_INTTOPTR) diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index a462b07..b122ed5 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -134,6 +134,12 @@ def G_PTRTOINT : GenericInstruction { let hasSideEffects = false; } +def G_PTRTOADDR : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type1:$src); + let hasSideEffects = false; +} + def G_BITCAST : GenericInstruction { let OutOperandList = (outs type0:$dst); let InOperandList = (ins type1:$src); diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td index efd8852..f55051d 100644 --- a/llvm/include/llvm/Target/GlobalISel/Combine.td +++ b/llvm/include/llvm/Target/GlobalISel/Combine.td @@ -440,8 +440,8 @@ def unary_undef_to_zero: GICombineRule< def unary_undef_to_undef_frags : GICombinePatFrag< (outs root:$dst), (ins), !foreach(op, - [G_TRUNC, G_BITCAST, G_ANYEXT, G_PTRTOINT, G_INTTOPTR, G_FPTOSI, - G_FPTOUI], + [G_TRUNC, G_BITCAST, G_ANYEXT, G_PTRTOINT, G_PTRTOADDR, G_INTTOPTR, + G_FPTOSI, G_FPTOUI], (pattern (op $dst, $x), (G_IMPLICIT_DEF $x)))>; def unary_undef_to_undef : GICombineRule< (defs root:$dst), diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index 7577792..5e58865 100644 --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -54,6 +54,7 @@ def : GINodeEquiv<G_TRUNC, trunc>; def : GINodeEquiv<G_BITCAST, bitconvert>; // G_INTTOPTR - SelectionDAG has no equivalent. // G_PTRTOINT - SelectionDAG has no equivalent. +// G_PTRTOADDR - SelectionDAG has no equivalent. def : GINodeEquiv<G_CONSTANT, imm>; // timm must not be materialized and therefore has no GlobalISel equivalent def : GINodeEquiv<G_FCONSTANT, fpimm>; diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index ce813e1..ce75a75 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -927,6 +927,7 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(fptoui, FPToUI); INSTKEYWORD(fptosi, FPToSI); INSTKEYWORD(inttoptr, IntToPtr); + INSTKEYWORD(ptrtoaddr, PtrToAddr); INSTKEYWORD(ptrtoint, PtrToInt); INSTKEYWORD(bitcast, BitCast); INSTKEYWORD(addrspacecast, AddrSpaceCast); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 5c007dc..beb0307 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4274,6 +4274,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { case lltok::kw_bitcast: case lltok::kw_addrspacecast: case lltok::kw_inttoptr: + // ptrtoaddr not supported in constant exprs (yet?). case lltok::kw_ptrtoint: { unsigned Opc = Lex.getUIntVal(); Type *DestTy = nullptr; @@ -7236,6 +7237,7 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_fptoui: case lltok::kw_fptosi: case lltok::kw_inttoptr: + case lltok::kw_ptrtoaddr: case lltok::kw_ptrtoint: return parseCast(Inst, PFS, KeywordVal); case lltok::kw_fptrunc: diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 31129b7..32ee0dd 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1275,6 +1275,7 @@ static int getDecodedCastOpcode(unsigned Val) { case bitc::CAST_SITOFP : return Instruction::SIToFP; case bitc::CAST_FPTRUNC : return Instruction::FPTrunc; case bitc::CAST_FPEXT : return Instruction::FPExt; + case bitc::CAST_PTRTOADDR: return Instruction::PtrToAddr; case bitc::CAST_PTRTOINT: return Instruction::PtrToInt; case bitc::CAST_INTTOPTR: return Instruction::IntToPtr; case bitc::CAST_BITCAST : return Instruction::BitCast; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 628b939..4f7deed 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -641,6 +641,7 @@ static unsigned getEncodedCastOpcode(unsigned Opcode) { case Instruction::SIToFP : return bitc::CAST_SITOFP; case Instruction::FPTrunc : return bitc::CAST_FPTRUNC; case Instruction::FPExt : return bitc::CAST_FPEXT; + case Instruction::PtrToAddr: return bitc::CAST_PTRTOADDR; case Instruction::PtrToInt: return bitc::CAST_PTRTOINT; case Instruction::IntToPtr: return bitc::CAST_INTTOPTR; case Instruction::BitCast : return bitc::CAST_BITCAST; diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index b1e851183..4fe3cd54 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -4814,7 +4814,8 @@ bool CombinerHelper::reassociationCanBreakAddressingModePattern( MachineInstr *ConvUseMI = &UseMI; unsigned ConvUseOpc = ConvUseMI->getOpcode(); while (ConvUseOpc == TargetOpcode::G_INTTOPTR || - ConvUseOpc == TargetOpcode::G_PTRTOINT) { + ConvUseOpc == TargetOpcode::G_PTRTOINT || + ConvUseOpc == TargetOpcode::G_PTRTOADDR) { Register DefReg = ConvUseMI->getOperand(0).getReg(); if (!MRI.hasOneNonDBGUse(DefReg)) break; diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp index 6650ad2..0fe2a09 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp @@ -491,6 +491,7 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known, } case TargetOpcode::G_INTTOPTR: case TargetOpcode::G_PTRTOINT: + case TargetOpcode::G_PTRTOADDR: if (DstTy.isVector()) break; // Fall through and handle them the same as zext/trunc. diff --git a/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp b/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp index 05923e5..134c0ce 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp @@ -100,6 +100,9 @@ LegacyLegalizerInfo::LegacyLegalizerInfo() { setLegalizeScalarToDifferentSizeStrategy( TargetOpcode::G_EXTRACT, 1, narrowToSmallerAndUnsupportedIfTooSmall); setScalarAction(TargetOpcode::G_FNEG, 0, {{1, Lower}}); + + setScalarAction(TargetOpcode::G_PTRTOADDR, 0, {{1, Lower}}); + // FIXME: Lower G_PTRTOADDR for vector types using less hacky approach } void LegacyLegalizerInfo::computeTables() { @@ -204,6 +207,10 @@ LegacyLegalizerInfo::getAspectAction(const InstrAspect &Aspect) const { if (Aspect.Type.isScalar() || Aspect.Type.isPointer()) return findScalarLegalAction(Aspect); assert(Aspect.Type.isVector()); + if (Aspect.Opcode == TargetOpcode::G_PTRTOADDR) { + // FIXME: need to handle this better + return {Lower, Aspect.Type}; + } return findVectorLegalAction(Aspect); } @@ -382,4 +389,3 @@ LegacyLegalizerInfo::getAction(const LegalityQuery &Query) const { LLVM_DEBUG(dbgs() << ".. (legacy) Legal\n"); return {Legal, 0, LLT{}}; } - diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 83ba71e..39fc200 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -1670,6 +1670,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, narrowScalarSrc(MI, NarrowTy, 1); Observer.changedInstr(MI); return Legalized; + case TargetOpcode::G_PTRTOADDR: case TargetOpcode::G_PTRTOINT: if (TypeIdx != 0) return UnableToLegalize; @@ -3305,6 +3306,7 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) { widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT); Observer.changedInstr(MI); return Legalized; + case TargetOpcode::G_PTRTOADDR: case TargetOpcode::G_PTRTOINT: if (TypeIdx != 0) return UnableToLegalize; @@ -4691,6 +4693,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) { return lowerEXT(MI); case G_TRUNC: return lowerTRUNC(MI); + case G_PTRTOADDR: + return lowerPTRTOADDR(MI); GISEL_VECREDUCE_CASES_NONSEQ return lowerVectorReduction(MI); case G_VAARG: @@ -5420,6 +5424,7 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, case G_FPTOUI_SAT: case G_INTTOPTR: case G_PTRTOINT: + case G_PTRTOADDR: case G_ADDRSPACE_CAST: case G_UADDO: case G_USUBO: @@ -7408,6 +7413,34 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerTRUNC(MachineInstr &MI) { } LegalizerHelper::LegalizeResult +LegalizerHelper::lowerPTRTOADDR(MachineInstr &MI) { + // Lower G_PTRTOADDR as a truncate to address width of G_PTROINT and then + // zero extend to the target width if there is no native support for it. + MachineRegisterInfo &MRI = *MIRBuilder.getMRI(); + const DataLayout &DL = MIRBuilder.getDataLayout(); + assert(MI.getOpcode() == TargetOpcode::G_PTRTOADDR); + auto DstReg = MI.getOperand(0).getReg(); + auto SrcReg = MI.getOperand(1).getReg(); + LLT SrcTy = MRI.getType(SrcReg); + + LLT AddrTy = getLLTForType( + *DL.getAddressType(MIRBuilder.getContext(), SrcTy.getAddressSpace()), DL); + LLT IntPtrTy = getLLTForType( + *DL.getIntPtrType(MIRBuilder.getContext(), SrcTy.getAddressSpace()), DL); + if (SrcTy.isVector()) { + AddrTy = LLT::vector(SrcTy.getElementCount(), AddrTy); + IntPtrTy = LLT::vector(SrcTy.getElementCount(), IntPtrTy); + } + auto PtrToInt = MIRBuilder.buildPtrToInt(IntPtrTy, SrcReg); + auto Addr = PtrToInt; + if (AddrTy != IntPtrTy) + Addr = MIRBuilder.buildTrunc(AddrTy, PtrToInt.getReg(0)); + MIRBuilder.buildZExtOrTrunc(DstReg, Addr.getReg(0)); + MI.eraseFromParent(); + return Legalized; +} + +LegalizerHelper::LegalizeResult LegalizerHelper::lowerRotateWithReverseRotate(MachineInstr &MI) { auto [Dst, DstTy, Src, SrcTy, Amt, AmtTy] = MI.getFirst3RegLLTs(); auto Zero = MIRBuilder.buildConstant(AmtTy, 0); diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index 1099882..c2a64b8 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1344,6 +1344,7 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) { break; } case TargetOpcode::G_INTTOPTR: + case TargetOpcode::G_PTRTOADDR: case TargetOpcode::G_PTRTOINT: case TargetOpcode::G_ADDRSPACE_CAST: { LLT DstTy = MRI->getType(MI->getOperand(0).getReg()); @@ -1366,6 +1367,11 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) { report("ptrtoint source type must be a pointer", MI); if (DstTy.isPointer()) report("ptrtoint result type must not be a pointer", MI); + } else if (MI->getOpcode() == TargetOpcode::G_PTRTOADDR) { + if (!SrcTy.isPointer()) + report("ptrtoaddr source type must be a pointer", MI); + if (DstTy.isPointer()) + report("ptrtoaddr result type must not be a pointer", MI); } else { assert(MI->getOpcode() == TargetOpcode::G_ADDRSPACE_CAST); if (!SrcTy.isPointer() || !DstTy.isPointer()) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index e6a1dc9..2411ad9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3883,6 +3883,18 @@ void SelectionDAGBuilder::visitSIToFP(const User &I) { setValue(&I, DAG.getNode(ISD::SINT_TO_FP, getCurSDLoc(), DestVT, N)); } +void SelectionDAGBuilder::visitPtrToAddr(const User &I) { + const auto &TLI = DAG.getTargetLoweringInfo(); + const DataLayout &DL = DAG.getDataLayout(); + // ptrtoaddr is equivalent to a truncate of ptrtoint to address/index width + auto Op0 = I.getOperand(0); + SDValue N = getValue(Op0); + EVT AddrVT = TLI.getValueType(DL, DL.getAddressType(Op0->getType())); + N = DAG.getPtrExtOrTrunc(N, getCurSDLoc(), AddrVT); + N = DAG.getZExtOrTrunc(N, getCurSDLoc(), TLI.getValueType(DL, I.getType())); + setValue(&I, N); +} + void SelectionDAGBuilder::visitPtrToInt(const User &I) { // What to do depends on the size of the integer and the size of the pointer. // We can either truncate, zero extend, or no-op, accordingly. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 35c15bc..108c014 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -575,6 +575,7 @@ private: void visitFPToSI(const User &I); void visitUIToFP(const User &I); void visitSIToFP(const User &I); + void visitPtrToAddr(const User &I); void visitPtrToInt(const User &I); void visitIntToPtr(const User &I); void visitBitCast(const User &I); diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 935afaf..2c3aed0 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1835,6 +1835,7 @@ int TargetLoweringBase::InstructionOpcodeToISD(unsigned Opcode) const { case SIToFP: return ISD::SINT_TO_FP; case FPTrunc: return ISD::FP_ROUND; case FPExt: return ISD::FP_EXTEND; + case PtrToAddr: return ISD::BITCAST; case PtrToInt: return ISD::BITCAST; case IntToPtr: return ISD::BITCAST; case BitCast: return ISD::BITCAST; diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 109d516..b19bbfe 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -824,6 +824,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case UIToFP: return "uitofp"; case SIToFP: return "sitofp"; case IntToPtr: return "inttoptr"; + case PtrToAddr: return "ptrtoaddr"; case PtrToInt: return "ptrtoint"; case BitCast: return "bitcast"; case AddrSpaceCast: return "addrspacecast"; diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 2d89ec1..81c65a3 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -2851,26 +2851,29 @@ unsigned CastInst::isEliminableCastPair( // same reason. const unsigned numCastOps = Instruction::CastOpsEnd - Instruction::CastOpsBegin; + // clang-format off static const uint8_t CastResults[numCastOps][numCastOps] = { - // T F F U S F F P I B A -+ - // R Z S P P I I T P 2 N T S | - // U E E 2 2 2 2 R E I T C C +- secondOp - // N X X U S F F N X N 2 V V | - // C T T I I P P C T T P T T -+ - { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // Trunc -+ - { 8, 1, 9,99,99, 2,17,99,99,99, 2, 3, 0}, // ZExt | - { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3, 0}, // SExt | - { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToUI | - { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToSI | - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // UIToFP +- firstOp - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // SIToFP | - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // FPTrunc | - { 99,99,99, 2, 2,99,99, 8, 2,99,99, 4, 0}, // FPExt | - { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3, 0}, // PtrToInt | - { 99,99,99,99,99,99,99,99,99,11,99,15, 0}, // IntToPtr | - { 5, 5, 5, 0, 0, 5, 5, 0, 0,16, 5, 1,14}, // BitCast | - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+ + // T F F U S F F P P I B A -+ + // R Z S P P I I T P 2 2 N T S | + // U E E 2 2 2 2 R E I A T C C +- secondOp + // N X X U S F F N X N D 2 V V | + // C T T I I P P C T T R P T T -+ + { 1, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // Trunc -+ + { 8, 1, 9,99,99, 2,17,99,99,99,99, 2, 3, 0}, // ZExt | + { 8, 0, 1,99,99, 0, 2,99,99,99,99, 0, 3, 0}, // SExt | + { 0, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // FPToUI | + { 0, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // FPToSI | + { 99,99,99, 0, 0,99,99, 0, 0,99,99,99, 4, 0}, // UIToFP +- firstOp + { 99,99,99, 0, 0,99,99, 0, 0,99,99,99, 4, 0}, // SIToFP | + { 99,99,99, 0, 0,99,99, 0, 0,99,99,99, 4, 0}, // FPTrunc | + { 99,99,99, 2, 2,99,99, 8, 2,99,99,99, 4, 0}, // FPExt | + { 1, 0, 0,99,99, 0, 0,99,99,99,99, 7, 3, 0}, // PtrToInt | + { 1, 0, 0,99,99, 0, 0,99,99,99,99,99, 3, 0}, // PtrToAddr | + { 99,99,99,99,99,99,99,99,99,11,99,99,15, 0}, // IntToPtr | + { 5, 5, 5, 0, 0, 5, 5, 0, 0,16,16, 5, 1,14}, // BitCast | + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+ }; + // clang-format on // TODO: This logic could be encoded into the table above and handled in the // switch below. @@ -3042,6 +3045,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore); case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore); case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore); + case PtrToAddr: return new PtrToAddrInst (S, Ty, Name, InsertBefore); case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); case BitCast: @@ -3343,6 +3347,7 @@ CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) { case Instruction::FPToSI: return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() && SrcEC == DstEC; + case Instruction::PtrToAddr: case Instruction::PtrToInt: if (SrcEC != DstEC) return false; @@ -3456,6 +3461,12 @@ PtrToIntInst::PtrToIntInst(Value *S, Type *Ty, const Twine &Name, assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt"); } +PtrToAddrInst::PtrToAddrInst(Value *S, Type *Ty, const Twine &Name, + InsertPosition InsertBefore) + : CastInst(Ty, PtrToAddr, S, Name, InsertBefore) { + assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToAddr"); +} + IntToPtrInst::IntToPtrInst(Value *S, Type *Ty, const Twine &Name, InsertPosition InsertBefore) : CastInst(Ty, IntToPtr, S, Name, InsertBefore) { @@ -4423,6 +4434,10 @@ PtrToIntInst *PtrToIntInst::cloneImpl() const { return new PtrToIntInst(getOperand(0), getType()); } +PtrToAddrInst *PtrToAddrInst::cloneImpl() const { + return new PtrToAddrInst(getOperand(0), getType()); +} + IntToPtrInst *IntToPtrInst::cloneImpl() const { return new IntToPtrInst(getOperand(0), getType()); } diff --git a/llvm/lib/SandboxIR/Context.cpp b/llvm/lib/SandboxIR/Context.cpp index fe34037..70ac68a 100644 --- a/llvm/lib/SandboxIR/Context.cpp +++ b/llvm/lib/SandboxIR/Context.cpp @@ -256,6 +256,7 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) { case llvm::Instruction::FPToUI: case llvm::Instruction::FPToSI: case llvm::Instruction::FPExt: + case llvm::Instruction::PtrToAddr: case llvm::Instruction::PtrToInt: case llvm::Instruction::IntToPtr: case llvm::Instruction::SIToFP: diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp index 0f002b0..26f1703 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp @@ -1360,6 +1360,7 @@ public: PtrParts visitAtomicCmpXchgInst(AtomicCmpXchgInst &AI); PtrParts visitGetElementPtrInst(GetElementPtrInst &GEP); + PtrParts visitPtrToAddrInst(PtrToAddrInst &PA); PtrParts visitPtrToIntInst(PtrToIntInst &PI); PtrParts visitIntToPtrInst(IntToPtrInst &IP); PtrParts visitAddrSpaceCastInst(AddrSpaceCastInst &I); @@ -1951,6 +1952,21 @@ PtrParts SplitPtrStructs::visitPtrToIntInst(PtrToIntInst &PI) { return {nullptr, nullptr}; } +PtrParts SplitPtrStructs::visitPtrToAddrInst(PtrToAddrInst &PA) { + Value *Ptr = PA.getPointerOperand(); + if (!isSplitFatPtr(Ptr->getType())) + return {nullptr, nullptr}; + IRB.SetInsertPoint(&PA); + + auto [Rsrc, Off] = getPtrParts(Ptr); + Value *Res = IRB.CreateIntCast(Off, PA.getType(), /*isSigned=*/false); + copyMetadata(Res, &PA); + Res->takeName(&PA); + SplitUsers.insert(&PA); + PA.replaceAllUsesWith(Res); + return {nullptr, nullptr}; +} + PtrParts SplitPtrStructs::visitIntToPtrInst(IntToPtrInst &IP) { if (!isSplitFatPtr(IP.getType())) return {nullptr, nullptr}; diff --git a/llvm/test/Assembler/ptrtoaddr-const.ll b/llvm/test/Assembler/ptrtoaddr-const.ll new file mode 100644 index 0000000..5816d10 --- /dev/null +++ b/llvm/test/Assembler/ptrtoaddr-const.ll @@ -0,0 +1,6 @@ +; RUN: not llvm-as --disable-output < %s 2>&1 | FileCheck %s +; ptrtoaddr is not currently support in constant expressions + +@i = global i32 0 +@global_cast = global i32 ptrtoaddr (ptr @i0 to i32) +; CHECK: [[#@LINE-1]]:27: error: expected value token diff --git a/llvm/test/Assembler/ptrtoaddr.ll b/llvm/test/Assembler/ptrtoaddr.ll new file mode 100644 index 0000000..7e1d97e --- /dev/null +++ b/llvm/test/Assembler/ptrtoaddr.ll @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s +target datalayout = "p1:64:64:64:32" + +define i32 @test_as0(ptr %p) { + %addr = ptrtoaddr ptr %p to i32 + ; CHECK: %addr = ptrtoaddr ptr %p to i32 + ret i32 %addr +} + +define i16 @test_as1(ptr addrspace(1) %p) { + %addr = ptrtoaddr ptr addrspace(1) %p to i16 + ; CHECK: %addr = ptrtoaddr ptr addrspace(1) %p to i16 + ret i16 %addr +} diff --git a/llvm/test/Bitcode/ptrtoaddr.ll b/llvm/test/Bitcode/ptrtoaddr.ll new file mode 100644 index 0000000..52eae16a --- /dev/null +++ b/llvm/test/Bitcode/ptrtoaddr.ll @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +target datalayout = "p1:64:64:64:32" + +define i32 @test_as0(ptr %p) { + %addr = ptrtoaddr ptr %p to i32 + ; CHECK: %addr = ptrtoaddr ptr %p to i32 + ret i32 %addr +} + +define i16 @test_as1(ptr addrspace(1) %p) { + %addr = ptrtoaddr ptr addrspace(1) %p to i16 + ; CHECK: %addr = ptrtoaddr ptr addrspace(1) %p to i16 + ret i16 %addr +} diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/knownbits-ptrtoaddr.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/knownbits-ptrtoaddr.mir new file mode 100644 index 0000000..3fcd24c --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/knownbits-ptrtoaddr.mir @@ -0,0 +1,108 @@ +# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5 +# RUN: llc -mtriple=amdgcn -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s +## Check that we don't incorrectly assume known zeroes for and extend of a truncated ptrtoaddr +--- +## We should see 48 unknown bits. +name: PtrToAddr +body: | + bb.0: + ; CHECK-LABEL: name: @PtrToAddr + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %4:_ KnownBits:???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? SignBits:1 + ; CHECK-NEXT: %5:_ KnownBits:???????????????????????????????????????????????? SignBits:1 + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s32) = COPY $vgpr2 + %3:_(s32) = COPY $vgpr3 + %4:_(p8) = G_MERGE_VALUES %0(s32), %1(s32), %2(s32), %3(s32) + %5:_(s48) = G_PTRTOADDR %4(p8) +... +--- +## We should see 208 high zeroes followed by 48 unknown bits for extending PtrToAddr. +## FIXME: this is currently wrong +name: PtrToAddrExt +body: | + bb.0: + ; CHECK-LABEL: name: @PtrToAddrExt + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %4:_ KnownBits:???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? SignBits:1 + ; CHECK-NEXT: %5:_ KnownBits:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? SignBits:128 + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s32) = COPY $vgpr2 + %3:_(s32) = COPY $vgpr3 + %4:_(p8) = G_MERGE_VALUES %0(s32), %1(s32), %2(s32), %3(s32) + %5:_(s256) = G_PTRTOADDR %4(p8) +... +--- +## We should see 32 unknown bits for truncating PtrToAddr. +name: PtrToAddrTrunc +body: | + bb.0: + ; CHECK-LABEL: name: @PtrToAddrTrunc + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %4:_ KnownBits:???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? SignBits:1 + ; CHECK-NEXT: %5:_ KnownBits:???????????????????????????????? SignBits:1 + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s32) = COPY $vgpr2 + %3:_(s32) = COPY $vgpr3 + %4:_(p8) = G_MERGE_VALUES %0(s32), %1(s32), %2(s32), %3(s32) + %5:_(s32) = G_PTRTOADDR %4(p8) +... +--- +## Cbeck that truncating and then extending the G_PTRTOADDR result fills +## all bits above the index bitwidth with known zeroes. +## We should see all zero high bits with 32 unknown bits. +name: PtrToAddrTruncExplicitExt +body: | + bb.0: + ; CHECK-LABEL: name: @PtrToAddrTruncExplicitExt + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %4:_ KnownBits:???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? SignBits:1 + ; CHECK-NEXT: %5:_ KnownBits:???????????????????????????????????????????????? SignBits:1 + ; CHECK-NEXT: %6:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %7:_ KnownBits:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000???????????????????????????????? SignBits:96 + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s32) = COPY $vgpr2 + %3:_(s32) = COPY $vgpr3 + %4:_(p8) = G_MERGE_VALUES %0(s32), %1(s32), %2(s32), %3(s32) + %5:_(s48) = G_PTRTOADDR %4(p8) + %6:_(s32) = G_TRUNC %5(s48) + %7:_(s128) = G_ZEXT %6(s32) +... +--- +## Same test again but this time have the G_PTRTOADDR do the truncation. +## We should see all zero high bits with 48 unknown bits. +name: PtrToAddrTruncImplicitExt +body: | + bb.0: + ; CHECK-LABEL: name: @PtrToAddrTruncImplicitExt + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %4:_ KnownBits:???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? SignBits:1 + ; CHECK-NEXT: %5:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %6:_ KnownBits:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000???????????????????????????????? SignBits:96 + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s32) = COPY $vgpr2 + %3:_(s32) = COPY $vgpr3 + %4:_(p8) = G_MERGE_VALUES %0(s32), %1(s32), %2(s32), %3(s32) + %5:_(s32) = G_PTRTOADDR %4(p8) + %6:_(s128) = G_ZEXT %5(s32) +... diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll new file mode 100644 index 0000000..6f31de9 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll @@ -0,0 +1,117 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=amdgcn -global-isel -verify-machineinstrs < %s | FileCheck %s +;; Check that we can lower ptrtoaddr differently from ptrtoint. +;; Includes an ignored argument so the registers actually need to be written +;; Also all functions are zeroext to show that non-address bits are masked off +;; instead of filling them with arbitrary data + +define zeroext i128 @ptrtoint(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoint: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: v_mov_b32_e32 v1, v5 +; CHECK-NEXT: v_mov_b32_e32 v2, v6 +; CHECK-NEXT: v_mov_b32_e32 v3, v7 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoint ptr addrspace(8) %ptr to i128 + ret i128 %ret +} + +define zeroext i48 @ptrtoaddr(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoaddr: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_and_b32_e32 v1, 0xffff, v5 +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoaddr ptr addrspace(8) %ptr to i48 + ret i48 %ret +} + +define <2 x i128> @ptrtoint_vec(ptr addrspace(8) %ignored, <2 x ptr addrspace(8)> %ptr) { +; CHECK-LABEL: ptrtoint_vec: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: v_mov_b32_e32 v1, v5 +; CHECK-NEXT: v_mov_b32_e32 v2, v6 +; CHECK-NEXT: v_mov_b32_e32 v3, v7 +; CHECK-NEXT: v_mov_b32_e32 v4, v8 +; CHECK-NEXT: v_mov_b32_e32 v5, v9 +; CHECK-NEXT: v_mov_b32_e32 v6, v10 +; CHECK-NEXT: v_mov_b32_e32 v7, v11 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoint <2 x ptr addrspace(8)> %ptr to <2 x i128> + ret <2 x i128> %ret +} + +;; Note: needs to be 2 x i64 instead of 2 x i48 since the latter is not supported. +define <2 x i64> @ptrtoaddr_vec(ptr addrspace(8) %ignored, <2 x ptr addrspace(8)> %ptr) { +; CHECK-LABEL: ptrtoaddr_vec: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: v_and_b32_e32 v1, 0xffff, v5 +; CHECK-NEXT: v_and_b32_e32 v3, 0xffff, v9 +; CHECK-NEXT: v_mov_b32_e32 v2, v8 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoaddr <2 x ptr addrspace(8)> %ptr to <2 x i64> + ret <2 x i64> %ret +} + +define zeroext i256 @ptrtoint_ext(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoint_ext: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: v_mov_b32_e32 v1, v5 +; CHECK-NEXT: v_mov_b32_e32 v2, v6 +; CHECK-NEXT: v_mov_b32_e32 v3, v7 +; CHECK-NEXT: v_mov_b32_e32 v4, 0 +; CHECK-NEXT: v_mov_b32_e32 v5, 0 +; CHECK-NEXT: v_mov_b32_e32 v6, 0 +; CHECK-NEXT: v_mov_b32_e32 v7, 0 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoint ptr addrspace(8) %ptr to i256 + ret i256 %ret +} + +;; Check that we extend the offset to i256 instead of reinterpreting all bits. +define zeroext i256 @ptrtoaddr_ext(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoaddr_ext: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: v_and_b32_e32 v1, 0xffff, v5 +; CHECK-NEXT: v_mov_b32_e32 v2, 0 +; CHECK-NEXT: v_mov_b32_e32 v3, 0 +; CHECK-NEXT: v_mov_b32_e32 v4, 0 +; CHECK-NEXT: v_mov_b32_e32 v5, 0 +; CHECK-NEXT: v_mov_b32_e32 v6, 0 +; CHECK-NEXT: v_mov_b32_e32 v7, 0 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoaddr ptr addrspace(8) %ptr to i256 + ret i256 %ret +} + +define zeroext i64 @ptrtoint_trunc(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoint_trunc: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: v_mov_b32_e32 v1, v5 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoint ptr addrspace(8) %ptr to i64 + ret i64 %ret +} + +define zeroext i16 @ptrtoaddr_trunc(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoaddr_trunc: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_and_b32_e32 v0, 0xffff, v4 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoaddr ptr addrspace(8) %ptr to i16 + ret i16 %ret +} diff --git a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll index 63c0463..4ed7608 100644 --- a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll +++ b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll @@ -255,6 +255,53 @@ define i32 @ptrtoint_offset(ptr addrspace(7) %ptr) { ret i32 %ret } +define i32 @ptrtoaddr(ptr addrspace(7) %ptr) { +; CHECK-LABEL: define i32 @ptrtoaddr +; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 +; CHECK-NEXT: [[RET:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 +; CHECK-NEXT: ret i32 [[RET]] +; + %ret = ptrtoaddr ptr addrspace(7) %ptr to i32 + ret i32 %ret +} + +define <2 x i32> @ptrtoaddr_vec(<2 x ptr addrspace(7)> %ptr) { +; CHECK-LABEL: define <2 x i32> @ptrtoaddr_vec +; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[PTR:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[PTR]], 0 +; CHECK-NEXT: [[RET:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[PTR]], 1 +; CHECK-NEXT: ret <2 x i32> [[RET]] +; + %ret = ptrtoaddr <2 x ptr addrspace(7)> %ptr to <2 x i32> + ret <2 x i32> %ret +} + +;; Check that we extend the offset to i160 instead of reinterpreting all bits. +define i160 @ptrtoaddr_ext(ptr addrspace(7) %ptr) { +; CHECK-LABEL: define i160 @ptrtoaddr_ext +; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 +; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 +; CHECK-NEXT: [[RET:%.*]] = zext i32 [[PTR_OFF]] to i160 +; CHECK-NEXT: ret i160 [[RET]] +; + %ret = ptrtoaddr ptr addrspace(7) %ptr to i160 + ret i160 %ret +} + +define i16 @ptrtoaddr_trunc(ptr addrspace(7) %ptr) { +; CHECK-LABEL: define i16 @ptrtoaddr_trunc +; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 +; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 +; CHECK-NEXT: [[RET:%.*]] = trunc i32 [[PTR_OFF]] to i16 +; CHECK-NEXT: ret i16 [[RET]] +; + %ret = ptrtoaddr ptr addrspace(7) %ptr to i16 + ret i16 %ret +} + define ptr addrspace(7) @inttoptr(i160 %v) { ; CHECK-LABEL: define { ptr addrspace(8), i32 } @inttoptr ; CHECK-SAME: (i160 [[V:%.*]]) #[[ATTR0]] { diff --git a/llvm/test/CodeGen/AMDGPU/ptrtoint-ptrtoaddr-p8.ll b/llvm/test/CodeGen/AMDGPU/ptrtoint-ptrtoaddr-p8.ll new file mode 100644 index 0000000..a230609 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/ptrtoint-ptrtoaddr-p8.ll @@ -0,0 +1,117 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=amdgcn -verify-machineinstrs < %s | FileCheck %s +;; Check that we can lower ptrtoaddr differently from ptrtoint. +;; Includes an ignored argument so the registers actually need to be written +;; Also all functions are zeroext to show that non-address bits are masked off +;; instead of filling them with arbitrary data + +define zeroext i128 @ptrtoint(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoint: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v3, v7 +; CHECK-NEXT: v_mov_b32_e32 v2, v6 +; CHECK-NEXT: v_mov_b32_e32 v1, v5 +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoint ptr addrspace(8) %ptr to i128 + ret i128 %ret +} + +define zeroext i48 @ptrtoaddr(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoaddr: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_and_b32_e32 v1, 0xffff, v5 +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoaddr ptr addrspace(8) %ptr to i48 + ret i48 %ret +} + +define <2 x i128> @ptrtoint_vec(ptr addrspace(8) %ignored, <2 x ptr addrspace(8)> %ptr) { +; CHECK-LABEL: ptrtoint_vec: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v3, v7 +; CHECK-NEXT: v_mov_b32_e32 v2, v6 +; CHECK-NEXT: v_mov_b32_e32 v1, v5 +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: v_mov_b32_e32 v4, v8 +; CHECK-NEXT: v_mov_b32_e32 v5, v9 +; CHECK-NEXT: v_mov_b32_e32 v6, v10 +; CHECK-NEXT: v_mov_b32_e32 v7, v11 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoint <2 x ptr addrspace(8)> %ptr to <2 x i128> + ret <2 x i128> %ret +} + +;; Note: needs to be 2 x i64 instead of 2 x i48 since the latter is not supported. +define <2 x i64> @ptrtoaddr_vec(ptr addrspace(8) %ignored, <2 x ptr addrspace(8)> %ptr) { +; CHECK-LABEL: ptrtoaddr_vec: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v2, v8 +; CHECK-NEXT: v_and_b32_e32 v1, 0xffff, v5 +; CHECK-NEXT: v_and_b32_e32 v3, 0xffff, v9 +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoaddr <2 x ptr addrspace(8)> %ptr to <2 x i64> + ret <2 x i64> %ret +} + +define zeroext i256 @ptrtoint_ext(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoint_ext: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v3, v7 +; CHECK-NEXT: v_mov_b32_e32 v2, v6 +; CHECK-NEXT: v_mov_b32_e32 v1, v5 +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: v_mov_b32_e32 v4, 0 +; CHECK-NEXT: v_mov_b32_e32 v5, 0 +; CHECK-NEXT: v_mov_b32_e32 v6, 0 +; CHECK-NEXT: v_mov_b32_e32 v7, 0 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoint ptr addrspace(8) %ptr to i256 + ret i256 %ret +} + +;; Check that we extend the offset to i256 instead of reinterpreting all bits. +define zeroext i256 @ptrtoaddr_ext(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoaddr_ext: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: v_and_b32_e32 v1, 0xffff, v5 +; CHECK-NEXT: v_mov_b32_e32 v2, 0 +; CHECK-NEXT: v_mov_b32_e32 v3, 0 +; CHECK-NEXT: v_mov_b32_e32 v4, 0 +; CHECK-NEXT: v_mov_b32_e32 v5, 0 +; CHECK-NEXT: v_mov_b32_e32 v6, 0 +; CHECK-NEXT: v_mov_b32_e32 v7, 0 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoaddr ptr addrspace(8) %ptr to i256 + ret i256 %ret +} + +define zeroext i64 @ptrtoint_trunc(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoint_trunc: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v1, v5 +; CHECK-NEXT: v_mov_b32_e32 v0, v4 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoint ptr addrspace(8) %ptr to i64 + ret i64 %ret +} + +define zeroext i16 @ptrtoaddr_trunc(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) { +; CHECK-LABEL: ptrtoaddr_trunc: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_and_b32_e32 v0, 0xffff, v4 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %ret = ptrtoaddr ptr addrspace(8) %ptr to i16 + ret i16 %ret +} diff --git a/llvm/test/CodeGen/X86/GlobalISel/ptrtoaddr.ll b/llvm/test/CodeGen/X86/GlobalISel/ptrtoaddr.ll new file mode 100644 index 0000000..9efe718 --- /dev/null +++ b/llvm/test/CodeGen/X86/GlobalISel/ptrtoaddr.ll @@ -0,0 +1,80 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=CHECK + +define i1 @ptrtoaddr_1(ptr %p) { +; CHECK-LABEL: ptrtoaddr_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: xorb $1, %al +; CHECK-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i1 + %ret = xor i1 %addr, 1 + ret i1 %ret +} + +define i8 @ptrtoaddr_8(ptr %p) { +; CHECK-LABEL: ptrtoaddr_8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notb %al +; CHECK-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i8 + %ret = xor i8 %addr, -1 + ret i8 %ret +} + +define i16 @ptrtoaddr_16(ptr %p) { +; CHECK-LABEL: ptrtoaddr_16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notw %ax +; CHECK-NEXT: # kill: def $ax killed $ax killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i16 + %ret = xor i16 %addr, -1 + ret i16 %ret +} + +define i32 @ptrtoaddr_32(ptr %p) { +; CHECK-LABEL: ptrtoaddr_32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notl %eax +; CHECK-NEXT: # kill: def $eax killed $eax killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i32 + %ret = xor i32 %addr, -1 + ret i32 %ret +} + +define i64 @ptrtoaddr_64(ptr %p) { +; CHECK-LABEL: ptrtoaddr_64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notq %rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %ret = xor i64 %addr, -1 + ret i64 %ret +} + +define i128 @ptrtoaddr_128(ptr %p) { +; CHECK-LABEL: ptrtoaddr_128: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: xorl %edx, %edx +; CHECK-NEXT: notq %rax +; CHECK-NEXT: notq %rdx +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i128 + %ret = xor i128 %addr, -1 + ret i128 %ret +} diff --git a/llvm/test/CodeGen/X86/ptrtoaddr.ll b/llvm/test/CodeGen/X86/ptrtoaddr.ll new file mode 100644 index 0000000..8d01870 --- /dev/null +++ b/llvm/test/CodeGen/X86/ptrtoaddr.ll @@ -0,0 +1,79 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-linux-gnu < %s -o - | FileCheck %s --check-prefix=CHECK + +define i1 @ptrtoaddr_1(ptr %p) { +; CHECK-LABEL: ptrtoaddr_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: xorb $1, %al +; CHECK-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i1 + %ret = xor i1 %addr, 1 + ret i1 %ret +} + +define i8 @ptrtoaddr_8(ptr %p) { +; CHECK-LABEL: ptrtoaddr_8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notb %al +; CHECK-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i8 + %ret = xor i8 %addr, -1 + ret i8 %ret +} + +define i16 @ptrtoaddr_16(ptr %p) { +; CHECK-LABEL: ptrtoaddr_16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notl %eax +; CHECK-NEXT: # kill: def $ax killed $ax killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i16 + %ret = xor i16 %addr, -1 + ret i16 %ret +} + +define i32 @ptrtoaddr_32(ptr %p) { +; CHECK-LABEL: ptrtoaddr_32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notl %eax +; CHECK-NEXT: # kill: def $eax killed $eax killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i32 + %ret = xor i32 %addr, -1 + ret i32 %ret +} + +define i64 @ptrtoaddr_64(ptr %p) { +; CHECK-LABEL: ptrtoaddr_64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notq %rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %ret = xor i64 %addr, -1 + ret i64 %ret +} + +define i128 @ptrtoaddr_128(ptr %p) { +; CHECK-LABEL: ptrtoaddr_128: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notq %rax +; CHECK-NEXT: movq $-1, %rdx +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i128 + %ret = xor i128 %addr, -1 + ret i128 %ret +} diff --git a/llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll b/llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll index 88eff97..0c2db4a 100644 --- a/llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll +++ b/llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll @@ -7,9 +7,9 @@ define i32 @nested(i32 %src) #0 { ; CHECK-SAME: i32 [[A0:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[BB15160:.*:]] ; CHECK-NEXT: [[T1:%.*]] = call token @llvm.experimental.convergence.entry() -; CHECK-NEXT: %"vl77672llvm.experimental.convergence.anchor()" = call token @llvm.experimental.convergence.anchor() -; CHECK-NEXT: %"op68297(vl77672)" = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[A0]]) [ "convergencectrl"(token %"vl77672llvm.experimental.convergence.anchor()") ] -; CHECK-NEXT: ret i32 %"op68297(vl77672)" +; CHECK-NEXT: %"vl14659llvm.experimental.convergence.anchor()" = call token @llvm.experimental.convergence.anchor() +; CHECK-NEXT: %"op15516(vl14659)" = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[A0]]) [ "convergencectrl"(token %"vl14659llvm.experimental.convergence.anchor()") ] +; CHECK-NEXT: ret i32 %"op15516(vl14659)" ; %t1 = call token @llvm.experimental.convergence.entry() %t2 = call token @llvm.experimental.convergence.anchor() diff --git a/llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll b/llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll index 35ac0fd..b9be105 100644 --- a/llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll +++ b/llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll @@ -8,18 +8,18 @@ define void @test(ptr, i32) { ; CHECK-NEXT: %"vl72693([[A1]], 1)" = add i32 [[A1]], 1 ; CHECK-NEXT: br label %[[BB16110:.*]] ; CHECK: [[BB16110]]: -; CHECK-NEXT: %"op10912(op18080, vl72693)" = phi i32 [ %"op18080(op10412, op17645)", %[[BB16110]] ], [ %"vl72693([[A1]], 1)", %[[BB76951]] ] -; CHECK-NEXT: %"op10912(op17645, vl72693)" = phi i32 [ %"op17645(op10912)70", %[[BB16110]] ], [ %"vl72693([[A1]], 1)", %[[BB76951]] ] -; CHECK-NEXT: %"op15084(op10912)" = mul i32 %"op10912(op18080, vl72693)", undef -; CHECK-NEXT: %"op16562(op15084)" = xor i32 -1, %"op15084(op10912)" -; CHECK-NEXT: %"op44627(op10912, op16562)" = add i32 %"op10912(op18080, vl72693)", %"op16562(op15084)" -; CHECK-NEXT: %"op17645(op10912)" = add i32 -1, %"op10912(op17645, vl72693)" -; CHECK-NEXT: %"op18080(op17645, op44627)" = add i32 %"op17645(op10912)", %"op44627(op10912, op16562)" -; CHECK-NEXT: %"op17720(op15084, op18080)" = mul i32 %"op15084(op10912)", %"op18080(op17645, op44627)" -; CHECK-NEXT: %"op16562(op17720)" = xor i32 -1, %"op17720(op15084, op18080)" -; CHECK-NEXT: %"op17430(op16562, op18080)" = add i32 %"op16562(op17720)", %"op18080(op17645, op44627)" +; CHECK-NEXT: %"op81283(op18080, vl72693)" = phi i32 [ %"op18080(op10412, op18131)", %[[BB16110]] ], [ %"vl72693([[A1]], 1)", %[[BB76951]] ] +; CHECK-NEXT: %"op81283(op18131, vl72693)" = phi i32 [ %"op18131(op81283)70", %[[BB16110]] ], [ %"vl72693([[A1]], 1)", %[[BB76951]] ] +; CHECK-NEXT: %"op13219(op81283)" = mul i32 %"op81283(op18080, vl72693)", undef +; CHECK-NEXT: %"op16562(op13219)" = xor i32 -1, %"op13219(op81283)" +; CHECK-NEXT: %"op12556(op16562, op81283)" = add i32 %"op16562(op13219)", %"op81283(op18080, vl72693)" +; CHECK-NEXT: %"op18131(op81283)" = add i32 -1, %"op81283(op18131, vl72693)" +; CHECK-NEXT: %"op18080(op12556, op18131)" = add i32 %"op12556(op16562, op81283)", %"op18131(op81283)" +; CHECK-NEXT: %"op17720(op13219, op18080)" = mul i32 %"op13219(op81283)", %"op18080(op12556, op18131)" +; CHECK-NEXT: %"op16562(op17720)" = xor i32 -1, %"op17720(op13219, op18080)" +; CHECK-NEXT: %"op17430(op16562, op18080)" = add i32 %"op16562(op17720)", %"op18080(op12556, op18131)" ; CHECK-NEXT: %"op10412(op17430)" = add i32 %"op17430(op16562, op18080)", undef -; CHECK-NEXT: %"op17720(op10412, op17720)" = mul i32 %"op10412(op17430)", %"op17720(op15084, op18080)" +; CHECK-NEXT: %"op17720(op10412, op17720)" = mul i32 %"op10412(op17430)", %"op17720(op13219, op18080)" ; CHECK-NEXT: %"op16562(op17720)1" = xor i32 -1, %"op17720(op10412, op17720)" ; CHECK-NEXT: %"op17430(op10412, op16562)" = add i32 %"op10412(op17430)", %"op16562(op17720)1" ; CHECK-NEXT: %"op10412(op17430)2" = add i32 %"op17430(op10412, op16562)", undef @@ -45,11 +45,11 @@ define void @test(ptr, i32) { ; CHECK-NEXT: %"op17720(op10412, op17720)21" = mul i32 %"op10412(op17430)20", %"op17720(op10412, op17720)17" ; CHECK-NEXT: %"op16562(op17720)22" = xor i32 -1, %"op17720(op10412, op17720)21" ; CHECK-NEXT: %"op17430(op10412, op16562)23" = add i32 %"op10412(op17430)20", %"op16562(op17720)22" -; CHECK-NEXT: %"op17645(op10912)24" = add i32 -9, %"op10912(op17645, vl72693)" -; CHECK-NEXT: %"op18080(op17430, op17645)" = add i32 %"op17430(op10412, op16562)23", %"op17645(op10912)24" -; CHECK-NEXT: %"op17720(op17720, op18080)" = mul i32 %"op17720(op10412, op17720)21", %"op18080(op17430, op17645)" +; CHECK-NEXT: %"op18131(op81283)24" = add i32 -9, %"op81283(op18131, vl72693)" +; CHECK-NEXT: %"op18080(op17430, op18131)" = add i32 %"op17430(op10412, op16562)23", %"op18131(op81283)24" +; CHECK-NEXT: %"op17720(op17720, op18080)" = mul i32 %"op17720(op10412, op17720)21", %"op18080(op17430, op18131)" ; CHECK-NEXT: %"op16562(op17720)25" = xor i32 -1, %"op17720(op17720, op18080)" -; CHECK-NEXT: %"op17430(op16562, op18080)26" = add i32 %"op16562(op17720)25", %"op18080(op17430, op17645)" +; CHECK-NEXT: %"op17430(op16562, op18080)26" = add i32 %"op16562(op17720)25", %"op18080(op17430, op18131)" ; CHECK-NEXT: %"op10412(op17430)27" = add i32 %"op17430(op16562, op18080)26", undef ; CHECK-NEXT: %"op17720(op10412, op17720)28" = mul i32 %"op10412(op17430)27", %"op17720(op17720, op18080)" ; CHECK-NEXT: %"op16562(op17720)29" = xor i32 -1, %"op17720(op10412, op17720)28" @@ -66,11 +66,11 @@ define void @test(ptr, i32) { ; CHECK-NEXT: %"op17720(op10412, op17720)40" = mul i32 %"op10412(op17430)39", %"op17720(op10412, op17720)36" ; CHECK-NEXT: %"op16562(op17720)41" = xor i32 -1, %"op17720(op10412, op17720)40" ; CHECK-NEXT: %"op17430(op10412, op16562)42" = add i32 %"op10412(op17430)39", %"op16562(op17720)41" -; CHECK-NEXT: %"op17645(op10912)43" = add i32 -14, %"op10912(op17645, vl72693)" -; CHECK-NEXT: %"op18080(op17430, op17645)44" = add i32 %"op17430(op10412, op16562)42", %"op17645(op10912)43" -; CHECK-NEXT: %"op17720(op17720, op18080)45" = mul i32 %"op17720(op10412, op17720)40", %"op18080(op17430, op17645)44" +; CHECK-NEXT: %"op18131(op81283)43" = add i32 -14, %"op81283(op18131, vl72693)" +; CHECK-NEXT: %"op18080(op17430, op18131)44" = add i32 %"op17430(op10412, op16562)42", %"op18131(op81283)43" +; CHECK-NEXT: %"op17720(op17720, op18080)45" = mul i32 %"op17720(op10412, op17720)40", %"op18080(op17430, op18131)44" ; CHECK-NEXT: %"op16562(op17720)46" = xor i32 -1, %"op17720(op17720, op18080)45" -; CHECK-NEXT: %"op17430(op16562, op18080)47" = add i32 %"op16562(op17720)46", %"op18080(op17430, op17645)44" +; CHECK-NEXT: %"op17430(op16562, op18080)47" = add i32 %"op16562(op17720)46", %"op18080(op17430, op18131)44" ; CHECK-NEXT: %"op10412(op17430)48" = add i32 %"op17430(op16562, op18080)47", undef ; CHECK-NEXT: %"op17720(op10412, op17720)49" = mul i32 %"op10412(op17430)48", %"op17720(op17720, op18080)45" ; CHECK-NEXT: %"op16562(op17720)50" = xor i32 -1, %"op17720(op10412, op17720)49" @@ -93,9 +93,9 @@ define void @test(ptr, i32) { ; CHECK-NEXT: %"op17430(op10412, op16562)67" = add i32 %"op10412(op17430)64", %"op16562(op17720)66" ; CHECK-NEXT: %"op10412(op17430)68" = add i32 %"op17430(op10412, op16562)67", undef ; CHECK-NEXT: %"op10412(op10412)69" = add i32 %"op10412(op17430)68", undef -; CHECK-NEXT: %"op17645(op10912)70" = add i32 -21, %"op10912(op17645, vl72693)" -; CHECK-NEXT: %"op18080(op10412, op17645)" = add i32 %"op10412(op10412)69", %"op17645(op10912)70" -; CHECK-NEXT: store i32 %"op18080(op10412, op17645)", ptr [[A0]], align 4 +; CHECK-NEXT: %"op18131(op81283)70" = add i32 -21, %"op81283(op18131, vl72693)" +; CHECK-NEXT: %"op18080(op10412, op18131)" = add i32 %"op10412(op10412)69", %"op18131(op81283)70" +; CHECK-NEXT: store i32 %"op18080(op10412, op18131)", ptr [[A0]], align 4 ; CHECK-NEXT: br label %[[BB16110]] ; bb: diff --git a/llvm/test/Transforms/IRNormalizer/reordering-basic.ll b/llvm/test/Transforms/IRNormalizer/reordering-basic.ll index fd09ce0..06e67e0 100644 --- a/llvm/test/Transforms/IRNormalizer/reordering-basic.ll +++ b/llvm/test/Transforms/IRNormalizer/reordering-basic.ll @@ -28,16 +28,16 @@ define double @baz(double %x) { ; CHECK-SAME: double [[A0:%.*]]) { ; CHECK-NEXT: [[BB76951:.*:]] ; CHECK-NEXT: [[IFCOND:%.*]] = fcmp one double [[A0]], 0.000000e+00 -; CHECK-NEXT: br i1 [[IFCOND]], label %[[BB91455:.*]], label %[[BB914551:.*]] -; CHECK: [[BB91455]]: -; CHECK-NEXT: %"vl15001bir()" = call double @bir() +; CHECK-NEXT: br i1 [[IFCOND]], label %[[BB47054:.*]], label %[[BB470541:.*]] +; CHECK: [[BB47054]]: +; CHECK-NEXT: %"vl16994bir()" = call double @bir() ; CHECK-NEXT: br label %[[BB17254:.*]] -; CHECK: [[BB914551]]: -; CHECK-NEXT: %"vl69719bar()" = call double @bar() +; CHECK: [[BB470541]]: +; CHECK-NEXT: %"vl88592bar()" = call double @bar() ; CHECK-NEXT: br label %[[BB17254]] ; CHECK: [[BB17254]]: -; CHECK-NEXT: %"op19734(vl15001, vl69719)" = phi double [ %"vl15001bir()", %[[BB91455]] ], [ %"vl69719bar()", %[[BB914551]] ] -; CHECK-NEXT: ret double %"op19734(vl15001, vl69719)" +; CHECK-NEXT: %"op16411(vl16994, vl88592)" = phi double [ %"vl16994bir()", %[[BB47054]] ], [ %"vl88592bar()", %[[BB470541]] ] +; CHECK-NEXT: ret double %"op16411(vl16994, vl88592)" ; entry: %ifcond = fcmp one double %x, 0.000000e+00 diff --git a/llvm/test/Transforms/IRNormalizer/reordering.ll b/llvm/test/Transforms/IRNormalizer/reordering.ll index 64abe8e..a3dbcb5 100644 --- a/llvm/test/Transforms/IRNormalizer/reordering.ll +++ b/llvm/test/Transforms/IRNormalizer/reordering.ll @@ -23,7 +23,7 @@ declare void @effecting() ; Place dead instruction(s) before the terminator define void @call_effecting() { ; CHECK-LABEL: define void @call_effecting() { -; CHECK-NEXT: bb15160: +; CHECK-NEXT: bb14885: ; CHECK-NEXT: call void @effecting() ; CHECK-NEXT: [[TMP0:%.*]] = add i32 0, 1 ; CHECK-NEXT: ret void @@ -51,7 +51,7 @@ exit: define void @dont_move_above_alloca() { ; CHECK-LABEL: define void @dont_move_above_alloca() { -; CHECK-NEXT: bb15160: +; CHECK-NEXT: bb14885: ; CHECK-NEXT: [[TMP0:%.*]] = alloca i32, align 4 ; CHECK-NEXT: call void @effecting() ; CHECK-NEXT: ret void @@ -65,7 +65,7 @@ declare void @effecting1() define void @dont_reorder_effecting() { ; CHECK-LABEL: define void @dont_reorder_effecting() { -; CHECK-NEXT: bb10075: +; CHECK-NEXT: bb45003: ; CHECK-NEXT: call void @effecting() ; CHECK-NEXT: call void @effecting1() ; CHECK-NEXT: ret void @@ -79,7 +79,7 @@ declare void @effecting2(i32) define void @dont_reorder_effecting1() { ; CHECK-LABEL: define void @dont_reorder_effecting1() { -; CHECK-NEXT: bb10075: +; CHECK-NEXT: bb45003: ; CHECK-NEXT: [[ONE:%.*]] = add i32 1, 1 ; CHECK-NEXT: call void @effecting2(i32 [[ONE]]) ; CHECK-NEXT: [[TWO:%.*]] = add i32 2, 2 |