[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-13 Thread Stanislav Mekhanoshin via cfe-commits

rampitec wrote:

> I suppose left shift of negative values is undefined because if you shift out 
> the sign bit you can overflow and get a positive value.

https://github.com/llvm/llvm-project/pull/68959

https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-13 Thread Stanislav Mekhanoshin via cfe-commits

rampitec wrote:

> I suppose left shift of negative values is undefined because if you shift out 
> the sign bit you can overflow and get a positive value.

Sounds like BS. It is defined. Unexpected maybe.

https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-13 Thread via cfe-commits

mikaelholmen wrote:

I suppose left shift of negative values is undefined because if you shift out 
the sign bit you can overflow and get a positive value.

https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-13 Thread Stanislav Mekhanoshin via cfe-commits

rampitec wrote:

I have a small little problem that I cannot build tip now:
```
FAILED: tools/llvm-remarkutil/CMakeFiles/llvm-remarkutil.dir/RemarkCounter.cpp.o
CCACHE_CPP2=yes CCACHE_HASHDIR=yes /usr/bin/ccache /usr/bin/clang++ 
-DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE 
-D_LIBCPP_ENABLE_HARDENED_MODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-D__STDC_LIMIT_MACROS -I/home/stas/work/llvm/ubsan/tools/llvm-remarkutil 
-I/home/stas/work/llvm/llvm/tools/llvm-remarkutil 
-I/home/stas/work/llvm/ubsan/include -I/home/stas/work/llvm/llvm/include -fPIC 
-fvisibility-inlines-hidden -Werror=date-time 
-Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter 
-Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic 
-Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough 
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor 
-Wdelete-non-virtual-dtor -Wstring-conversion -Wmisleading-indentation 
-Wctad-maybe-unsupported -fdiagnostics-color -g  -fno-exceptions 
-funwind-tables -fno-rtti -std=c++17 -MD -MT 
tools/llvm-remarkutil/CMakeFiles/llvm-remarkutil.dir/RemarkCounter.cpp.o -MF 
tools/llvm-remarkutil/CMakeFiles/llvm-remarkutil.dir/RemarkCounter.cpp.o.d -o 
tools/llvm-remarkutil/CMakeFiles/llvm-remarkutil.dir/RemarkCounter.cpp.o -c 
/home/stas/work/llvm/llvm/tools/llvm-remarkutil/RemarkCounter.cpp
In file included from 
/home/stas/work/llvm/llvm/tools/llvm-remarkutil/RemarkCounter.cpp:13:
/home/stas/work/llvm/llvm/tools/llvm-remarkutil/RemarkCounter.h:90:14: error: 
call to deleted constructor of 'llvm::Error'
  return E;
 ^
```

https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-13 Thread Stanislav Mekhanoshin via cfe-commits

rampitec wrote:

> > Hi @rampitec
> > With UBSan built binaries the MC/AMDGPU/literals.s testcase fails and 
> > triggers UB like
> > ```
> > 07:33:04 ../lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp:2246:59: 
> > runtime error: left shift of negative value -54321
> > 07:33:04 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
> > ../lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp:2246:59 
> > ```
> > 
> > 
> > It's this new shift that it complains on:
> > ```
> > Val = AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? Val << 32 : 
> > Lo_32(Val);
> > ```
> 
> I am happy to fix it, but I do not understand how a LEFT shift can be a UB? 
> Low bits will be zero, right? High bits will be disposed. I really do not 
> understand.

Building ubsan now...

https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-13 Thread Stanislav Mekhanoshin via cfe-commits

rampitec wrote:

> Hi @rampitec
> 
> With UBSan built binaries the MC/AMDGPU/literals.s testcase fails and 
> triggers UB like
> 
> ```
> 07:33:04 ../lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp:2246:59: runtime 
> error: left shift of negative value -54321
> 07:33:04 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
> ../lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp:2246:59 
> ```
> 
> It's this new shift that it complains on:
> 
> ```
> Val = AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? Val << 32 : Lo_32(Val);
> ```

I am happy to fix it, but I do not understand how a LEFT shift can be a UB? Low 
bits will be zero, right? High bits will be disposed. I really do not 
understand.

https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-13 Thread via cfe-commits

mikaelholmen wrote:

Hi @rampitec 

With UBSan built binaries the
 MC/AMDGPU/literals.s
testcase fails and triggers UB like
```
07:33:04 ../lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp:2246:59: runtime 
error: left shift of negative value -54321
07:33:04 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
../lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp:2246:59 
```
It's this new shift that it complains on:
```
Val = AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? Val << 32 : Lo_32(Val);
```

https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-12 Thread Stanislav Mekhanoshin via cfe-commits

https://github.com/rampitec closed 
https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-12 Thread Stanislav Mekhanoshin via cfe-commits

https://github.com/rampitec updated 
https://github.com/llvm/llvm-project/pull/68740

>From cc9e065a9218eb36750a2c2a4a4d08fae3f329fa Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin 
Date: Wed, 4 Oct 2023 13:36:25 -0700
Subject: [PATCH 1/6] [AMDGPU] Change the representation of double literals in
 operands

A 64-bit literal can be used as a 32-bit zero or sign extended
operand. In case of double zeroes are added to the low 32 bits.
Currently asm parser stores only high 32 bits of a double into
an operand. To support codegen as requested by the
https://github.com/llvm/llvm-project/issues/67781 we need to
change the representation to store a full 64-bit value so that
codegen can simply add immediates to an instruction.

There is some code to support compatibility with existing tests
and asm kernels. We allow to use short hex strings to represent
only a high 32 bit of a double value as a valid literal.
---
 .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp  | 21 --
 .../Disassembler/AMDGPUDisassembler.cpp   | 28 ++-
 .../AMDGPU/Disassembler/AMDGPUDisassembler.h  |  9 --
 .../AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp | 12 +---
 .../AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h   |  2 +-
 .../MCTargetDesc/AMDGPUMCCodeEmitter.cpp  |  3 ++
 llvm/lib/Target/AMDGPU/SIRegisterInfo.td  |  4 ++-
 .../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp|  7 +
 llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h |  3 ++
 9 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp 
b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 35656bcaea1af7f..0553d3f20b21c56 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -2140,9 +2140,10 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst , 
int64_t Val, bool ApplyMo
   const_cast(AsmParser)->Warning(Inst.getLoc(),
   "Can't encode literal as exact 64-bit floating-point operand. "
   "Low 32-bits will be set to zero");
+  Val &= 0xu;
 }
 
-Inst.addOperand(MCOperand::createImm(Literal.lshr(32).getZExtValue()));
+Inst.addOperand(MCOperand::createImm(Val));
 setImmKindLiteral();
 return;
   }
@@ -2241,7 +2242,10 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst , 
int64_t Val, bool ApplyMo
   return;
 }
 
-Inst.addOperand(MCOperand::createImm(Lo_32(Val)));
+if (isInt<32>(Val) || isUInt<32>(Val))
+  Val = AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? Val << 32 : Lo_32(Val);
+
+Inst.addOperand(MCOperand::createImm(Val));
 setImmKindLiteral();
 return;
 
@@ -4297,7 +4301,18 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst 
,
   continue;
 
 if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
-  uint32_t Value = static_cast(MO.getImm());
+  uint64_t Value = static_cast(MO.getImm());
+  bool IsFP = AMDGPU::isSISrcFPOperand(Desc, OpIdx);
+  bool IsValid32Op = AMDGPU::isValid32BitLiteral(Value, IsFP);
+
+  if (!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value)) {
+Error(getLitLoc(Operands), "invalid operand for instruction");
+return false;
+  }
+
+  if (IsFP && IsValid32Op)
+Value = Hi_32(Value);
+
   if (NumLiterals == 0 || LiteralValue != Value) {
 LiteralValue = Value;
 ++NumLiterals;
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp 
b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 439762bc6caf786..8c49c9a9c87772e 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -378,6 +378,15 @@ static DecodeStatus decodeOperand_AVLdSt_Any(MCInst , 
unsigned Imm,
   return addOperand(Inst, DAsm->decodeSrcOp(Opw, Imm | 256));
 }
 
+static DecodeStatus
+decodeOperand_VSrc_f64(MCInst , unsigned Imm, uint64_t Addr,
+   const MCDisassembler *Decoder) {
+  assert(Imm < (1 << 9) && "9-bit encoding");
+  auto DAsm = static_cast(Decoder);
+  return addOperand(Inst, DAsm->decodeSrcOp(AMDGPUDisassembler::OPW64, Imm,
+false, 64, true));
+}
+
 static DecodeStatus
 DecodeAVLdSt_32RegisterClass(MCInst , unsigned Imm, uint64_t Addr,
  const MCDisassembler *Decoder) {
@@ -1218,7 +1227,7 @@ 
AMDGPUDisassembler::decodeMandatoryLiteralConstant(unsigned Val) const {
   return MCOperand::createImm(Literal);
 }
 
-MCOperand AMDGPUDisassembler::decodeLiteralConstant() const {
+MCOperand AMDGPUDisassembler::decodeLiteralConstant(bool ExtendFP64) const {
   // For now all literal constants are supposed to be unsigned integer
   // ToDo: deal with signed/unsigned 64-bit integer constants
   // ToDo: deal with float/double constants
@@ -1228,9 +1237,11 @@ MCOperand AMDGPUDisassembler::decodeLiteralConstant() 
const {
   

[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-12 Thread Stanislav Mekhanoshin via cfe-commits

https://github.com/rampitec updated 
https://github.com/llvm/llvm-project/pull/68740

>From cc9e065a9218eb36750a2c2a4a4d08fae3f329fa Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin 
Date: Wed, 4 Oct 2023 13:36:25 -0700
Subject: [PATCH 1/6] [AMDGPU] Change the representation of double literals in
 operands

A 64-bit literal can be used as a 32-bit zero or sign extended
operand. In case of double zeroes are added to the low 32 bits.
Currently asm parser stores only high 32 bits of a double into
an operand. To support codegen as requested by the
https://github.com/llvm/llvm-project/issues/67781 we need to
change the representation to store a full 64-bit value so that
codegen can simply add immediates to an instruction.

There is some code to support compatibility with existing tests
and asm kernels. We allow to use short hex strings to represent
only a high 32 bit of a double value as a valid literal.
---
 .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp  | 21 --
 .../Disassembler/AMDGPUDisassembler.cpp   | 28 ++-
 .../AMDGPU/Disassembler/AMDGPUDisassembler.h  |  9 --
 .../AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp | 12 +---
 .../AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h   |  2 +-
 .../MCTargetDesc/AMDGPUMCCodeEmitter.cpp  |  3 ++
 llvm/lib/Target/AMDGPU/SIRegisterInfo.td  |  4 ++-
 .../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp|  7 +
 llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h |  3 ++
 9 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp 
b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 35656bcaea1af7f..0553d3f20b21c56 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -2140,9 +2140,10 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst , 
int64_t Val, bool ApplyMo
   const_cast(AsmParser)->Warning(Inst.getLoc(),
   "Can't encode literal as exact 64-bit floating-point operand. "
   "Low 32-bits will be set to zero");
+  Val &= 0xu;
 }
 
-Inst.addOperand(MCOperand::createImm(Literal.lshr(32).getZExtValue()));
+Inst.addOperand(MCOperand::createImm(Val));
 setImmKindLiteral();
 return;
   }
@@ -2241,7 +2242,10 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst , 
int64_t Val, bool ApplyMo
   return;
 }
 
-Inst.addOperand(MCOperand::createImm(Lo_32(Val)));
+if (isInt<32>(Val) || isUInt<32>(Val))
+  Val = AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? Val << 32 : Lo_32(Val);
+
+Inst.addOperand(MCOperand::createImm(Val));
 setImmKindLiteral();
 return;
 
@@ -4297,7 +4301,18 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst 
,
   continue;
 
 if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
-  uint32_t Value = static_cast(MO.getImm());
+  uint64_t Value = static_cast(MO.getImm());
+  bool IsFP = AMDGPU::isSISrcFPOperand(Desc, OpIdx);
+  bool IsValid32Op = AMDGPU::isValid32BitLiteral(Value, IsFP);
+
+  if (!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value)) {
+Error(getLitLoc(Operands), "invalid operand for instruction");
+return false;
+  }
+
+  if (IsFP && IsValid32Op)
+Value = Hi_32(Value);
+
   if (NumLiterals == 0 || LiteralValue != Value) {
 LiteralValue = Value;
 ++NumLiterals;
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp 
b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 439762bc6caf786..8c49c9a9c87772e 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -378,6 +378,15 @@ static DecodeStatus decodeOperand_AVLdSt_Any(MCInst , 
unsigned Imm,
   return addOperand(Inst, DAsm->decodeSrcOp(Opw, Imm | 256));
 }
 
+static DecodeStatus
+decodeOperand_VSrc_f64(MCInst , unsigned Imm, uint64_t Addr,
+   const MCDisassembler *Decoder) {
+  assert(Imm < (1 << 9) && "9-bit encoding");
+  auto DAsm = static_cast(Decoder);
+  return addOperand(Inst, DAsm->decodeSrcOp(AMDGPUDisassembler::OPW64, Imm,
+false, 64, true));
+}
+
 static DecodeStatus
 DecodeAVLdSt_32RegisterClass(MCInst , unsigned Imm, uint64_t Addr,
  const MCDisassembler *Decoder) {
@@ -1218,7 +1227,7 @@ 
AMDGPUDisassembler::decodeMandatoryLiteralConstant(unsigned Val) const {
   return MCOperand::createImm(Literal);
 }
 
-MCOperand AMDGPUDisassembler::decodeLiteralConstant() const {
+MCOperand AMDGPUDisassembler::decodeLiteralConstant(bool ExtendFP64) const {
   // For now all literal constants are supposed to be unsigned integer
   // ToDo: deal with signed/unsigned 64-bit integer constants
   // ToDo: deal with float/double constants
@@ -1228,9 +1237,11 @@ MCOperand AMDGPUDisassembler::decodeLiteralConstant() 
const {
   

[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-12 Thread Stanislav Mekhanoshin via cfe-commits

rampitec wrote:

> LGTM modulo one remaining comment about validateVOPLiteral.

Done.

https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-12 Thread Stanislav Mekhanoshin via cfe-commits


@@ -2241,7 +2242,10 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst , 
int64_t Val, bool ApplyMo
   return;
 }
 
-Inst.addOperand(MCOperand::createImm(Lo_32(Val)));
+if (isInt<32>(Val) || isUInt<32>(Val))
+  Val = AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? Val << 32 : Lo_32(Val);

rampitec wrote:

> I still find the Int/UInt check confusing here. How about:

Done.

https://github.com/llvm/llvm-project/pull/68740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AMDGPU] Change the representation of double literals in operands (PR #68740)

2023-10-12 Thread Stanislav Mekhanoshin via cfe-commits

https://github.com/rampitec updated 
https://github.com/llvm/llvm-project/pull/68740

>From cc9e065a9218eb36750a2c2a4a4d08fae3f329fa Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin 
Date: Wed, 4 Oct 2023 13:36:25 -0700
Subject: [PATCH 1/3] [AMDGPU] Change the representation of double literals in
 operands

A 64-bit literal can be used as a 32-bit zero or sign extended
operand. In case of double zeroes are added to the low 32 bits.
Currently asm parser stores only high 32 bits of a double into
an operand. To support codegen as requested by the
https://github.com/llvm/llvm-project/issues/67781 we need to
change the representation to store a full 64-bit value so that
codegen can simply add immediates to an instruction.

There is some code to support compatibility with existing tests
and asm kernels. We allow to use short hex strings to represent
only a high 32 bit of a double value as a valid literal.
---
 .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp  | 21 --
 .../Disassembler/AMDGPUDisassembler.cpp   | 28 ++-
 .../AMDGPU/Disassembler/AMDGPUDisassembler.h  |  9 --
 .../AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp | 12 +---
 .../AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h   |  2 +-
 .../MCTargetDesc/AMDGPUMCCodeEmitter.cpp  |  3 ++
 llvm/lib/Target/AMDGPU/SIRegisterInfo.td  |  4 ++-
 .../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp|  7 +
 llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h |  3 ++
 9 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp 
b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 35656bcaea1af7f..0553d3f20b21c56 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -2140,9 +2140,10 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst , 
int64_t Val, bool ApplyMo
   const_cast(AsmParser)->Warning(Inst.getLoc(),
   "Can't encode literal as exact 64-bit floating-point operand. "
   "Low 32-bits will be set to zero");
+  Val &= 0xu;
 }
 
-Inst.addOperand(MCOperand::createImm(Literal.lshr(32).getZExtValue()));
+Inst.addOperand(MCOperand::createImm(Val));
 setImmKindLiteral();
 return;
   }
@@ -2241,7 +2242,10 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst , 
int64_t Val, bool ApplyMo
   return;
 }
 
-Inst.addOperand(MCOperand::createImm(Lo_32(Val)));
+if (isInt<32>(Val) || isUInt<32>(Val))
+  Val = AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? Val << 32 : Lo_32(Val);
+
+Inst.addOperand(MCOperand::createImm(Val));
 setImmKindLiteral();
 return;
 
@@ -4297,7 +4301,18 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst 
,
   continue;
 
 if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
-  uint32_t Value = static_cast(MO.getImm());
+  uint64_t Value = static_cast(MO.getImm());
+  bool IsFP = AMDGPU::isSISrcFPOperand(Desc, OpIdx);
+  bool IsValid32Op = AMDGPU::isValid32BitLiteral(Value, IsFP);
+
+  if (!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value)) {
+Error(getLitLoc(Operands), "invalid operand for instruction");
+return false;
+  }
+
+  if (IsFP && IsValid32Op)
+Value = Hi_32(Value);
+
   if (NumLiterals == 0 || LiteralValue != Value) {
 LiteralValue = Value;
 ++NumLiterals;
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp 
b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 439762bc6caf786..8c49c9a9c87772e 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -378,6 +378,15 @@ static DecodeStatus decodeOperand_AVLdSt_Any(MCInst , 
unsigned Imm,
   return addOperand(Inst, DAsm->decodeSrcOp(Opw, Imm | 256));
 }
 
+static DecodeStatus
+decodeOperand_VSrc_f64(MCInst , unsigned Imm, uint64_t Addr,
+   const MCDisassembler *Decoder) {
+  assert(Imm < (1 << 9) && "9-bit encoding");
+  auto DAsm = static_cast(Decoder);
+  return addOperand(Inst, DAsm->decodeSrcOp(AMDGPUDisassembler::OPW64, Imm,
+false, 64, true));
+}
+
 static DecodeStatus
 DecodeAVLdSt_32RegisterClass(MCInst , unsigned Imm, uint64_t Addr,
  const MCDisassembler *Decoder) {
@@ -1218,7 +1227,7 @@ 
AMDGPUDisassembler::decodeMandatoryLiteralConstant(unsigned Val) const {
   return MCOperand::createImm(Literal);
 }
 
-MCOperand AMDGPUDisassembler::decodeLiteralConstant() const {
+MCOperand AMDGPUDisassembler::decodeLiteralConstant(bool ExtendFP64) const {
   // For now all literal constants are supposed to be unsigned integer
   // ToDo: deal with signed/unsigned 64-bit integer constants
   // ToDo: deal with float/double constants
@@ -1228,9 +1237,11 @@ MCOperand AMDGPUDisassembler::decodeLiteralConstant() 
const {