aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Richardson <alexrichardson@google.com>2025-06-11 16:51:27 -0700
committerAlex Richardson <alexrichardson@google.com>2025-06-11 16:51:27 -0700
commit18c2f3b974c1f094c99d7f8db4d2ed398a9a8cf1 (patch)
treecc1245b1f76f561da83a95bccdb0aaa26832f700
parentc2f0af514beb7618660cf8d145fa9e49fb78869c (diff)
downloadllvm-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]
-rw-r--r--llvm/docs/GlobalISel/GenericOpcode.rst9
-rw-r--r--llvm/docs/LangRef.rst55
-rw-r--r--llvm/include/llvm-c/Core.h1
-rw-r--r--llvm/include/llvm/Analysis/TargetTransformInfoImpl.h7
-rw-r--r--llvm/include/llvm/AsmParser/LLToken.h1
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h1
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h3
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h1
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h5
-rw-r--r--llvm/include/llvm/IR/InstVisitor.h1
-rw-r--r--llvm/include/llvm/IR/Instruction.def53
-rw-r--r--llvm/include/llvm/IR/Instructions.h40
-rw-r--r--llvm/include/llvm/SandboxIR/Instruction.h1
-rw-r--r--llvm/include/llvm/Support/TargetOpcodes.def3
-rw-r--r--llvm/include/llvm/Target/GenericOpcodes.td6
-rw-r--r--llvm/include/llvm/Target/GlobalISel/Combine.td4
-rw-r--r--llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td1
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp2
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp1
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp1
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp3
-rw-r--r--llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp1
-rw-r--r--llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp8
-rw-r--r--llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp33
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp6
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp12
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h1
-rw-r--r--llvm/lib/CodeGen/TargetLoweringBase.cpp1
-rw-r--r--llvm/lib/IR/Instruction.cpp1
-rw-r--r--llvm/lib/IR/Instructions.cpp51
-rw-r--r--llvm/lib/SandboxIR/Context.cpp1
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp16
-rw-r--r--llvm/test/Assembler/ptrtoaddr-const.ll6
-rw-r--r--llvm/test/Assembler/ptrtoaddr.ll14
-rw-r--r--llvm/test/Bitcode/ptrtoaddr.ll14
-rw-r--r--llvm/test/CodeGen/AMDGPU/GlobalISel/knownbits-ptrtoaddr.mir108
-rw-r--r--llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll117
-rw-r--r--llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll47
-rw-r--r--llvm/test/CodeGen/AMDGPU/ptrtoint-ptrtoaddr-p8.ll117
-rw-r--r--llvm/test/CodeGen/X86/GlobalISel/ptrtoaddr.ll80
-rw-r--r--llvm/test/CodeGen/X86/ptrtoaddr.ll79
-rw-r--r--llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll6
-rw-r--r--llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll44
-rw-r--r--llvm/test/Transforms/IRNormalizer/reordering-basic.ll14
-rw-r--r--llvm/test/Transforms/IRNormalizer/reordering.ll8
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