Skip to content

Commit

Permalink
[X86-64] Only check if DestReg is not null if it is read from
Browse files Browse the repository at this point in the history
[Test] Add test to verify the change.
  • Loading branch information
martin-fink authored and bharadwajy committed Jan 11, 2022
1 parent 8698fcc commit 91c5bfa
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 10 deletions.
37 changes: 27 additions & 10 deletions X86/X86MachineInstructionRaiser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1577,8 +1577,6 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
unsigned int MemAlignment = getInstructionMemOpSize(Opcode);
Type *DestopTy = getPhysRegOperandType(MI, DestIndex);
Value *DestValue = getRegOrArgValue(DestPReg, MI.getParent()->getNumber());
assert(DestValue != nullptr &&
"Encountered instruction with undefined register");

// Verify sanity of the instruction.
// SSE2 registers are always of a fixed size and might not be equal to
Expand All @@ -1591,13 +1589,15 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
unsigned int MemoryRefOpIndex = getMemoryRefOpIndex(MI);
Value *LoadValue =
loadMemoryRefValue(MI, MemRefValue, MemoryRefOpIndex, DestopTy);
// Cast DestValue to the DestopTy, as for single-precision FP ops
// DestValue type and DestopTy might be different.
if (isSSE2Reg(DestPReg)) {
DestValue = getRaisedValues()->reinterpretSSERegValue(DestValue, DestopTy,
RaisedBB);
} else {
DestValue = getRaisedValues()->castValue(DestValue, DestopTy, RaisedBB);
if (DestValue != nullptr) {
// Cast DestValue to the DestopTy, as for single-precision FP ops
// DestValue type and DestopTy might be different.
if (isSSE2Reg(DestPReg)) {
DestValue = getRaisedValues()->reinterpretSSERegValue(DestValue, DestopTy,
RaisedBB);
} else {
DestValue = getRaisedValues()->castValue(DestValue, DestopTy, RaisedBB);
}
}
Instruction *BinOpInst = nullptr;

Expand All @@ -1606,6 +1606,7 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
case X86::ADD32rm:
case X86::ADD16rm:
case X86::ADD8rm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
// Create add instruction
BinOpInst = BinaryOperator::CreateAdd(DestValue, LoadValue);
AffectedEFlags.insert(EFLAGS::PF);
Expand All @@ -1614,18 +1615,21 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
case X86::AND32rm:
case X86::AND16rm:
case X86::AND8rm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
// Create and instruction
BinOpInst = BinaryOperator::CreateAnd(DestValue, LoadValue);
AffectedEFlags.insert(EFLAGS::PF);
} break;
case X86::OR32rm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
// Create or instruction
BinOpInst = BinaryOperator::CreateOr(DestValue, LoadValue);
AffectedEFlags.insert(EFLAGS::PF);
} break;
case X86::IMUL16rm:
case X86::IMUL32rm:
case X86::IMUL64rm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
// One-operand form of IMUL
// Create mul instruction
BinOpInst = BinaryOperator::CreateMul(DestValue, LoadValue);
Expand All @@ -1636,7 +1640,8 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
case X86::IMUL32rmi8:
case X86::IMUL64rmi8:
case X86::IMUL64rmi32: {
// Two-operand form of IMUL
// We don't read from DestValue, so we don't need to check if it is null
// Three-operand form of IMUL
// Get index of memory reference in the instruction.
int MemoryRefOpIndex = getMemoryRefOpIndex(MI);
// The index of the memory reference operand should be 1
Expand All @@ -1657,6 +1662,7 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
case X86::XOR16rm:
case X86::XOR32rm:
case X86::XOR64rm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
// Create xor instruction
BinOpInst = BinaryOperator::CreateXor(DestValue, LoadValue);
ClearedEFlags.insert(EFLAGS::OF);
Expand All @@ -1667,24 +1673,29 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
} break;
case X86::ADDSSrm_Int:
case X86::ADDSDrm_Int: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
BinOpInst = BinaryOperator::CreateFAdd(DestValue, LoadValue);
} break;
case X86::SUBSSrm_Int:
case X86::SUBSDrm_Int: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
BinOpInst = BinaryOperator::CreateFSub(DestValue, LoadValue);
} break;
case X86::MULSDrm_Int:
case X86::MULSSrm_Int: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
BinOpInst = BinaryOperator::CreateFMul(DestValue, LoadValue);
} break;
case X86::DIVSDrm_Int:
case X86::DIVSSrm_Int: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
BinOpInst = BinaryOperator::CreateFDiv(DestValue, LoadValue);
} break;
case X86::MAXSDrm_Int:
case X86::MAXSSrm_Int:
case X86::MINSDrm_Int:
case X86::MINSSrm_Int: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
bool isMax = instrNameStartsWith(MI, "MAX");
std::string nameString = isMax ? "max" : "min";

Expand All @@ -1702,6 +1713,7 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
case X86::ORPSrm:
case X86::XORPDrm:
case X86::XORPSrm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
LLVMContext &Ctx(MF.getFunction().getContext());
auto Int128Ty = Type::getInt128Ty(Ctx);
// BitCast operands to integer types to perform and/or/xor operation
Expand Down Expand Up @@ -1734,22 +1746,26 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
BinOpInst = new BitCastInst(Result, DestopTy);
} break;
case X86::PANDrm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
BinOpInst = BinaryOperator::CreateAnd(DestValue, LoadValue);
} break;
case X86::PANDNrm: {
DestValue = BinaryOperator::CreateNot(DestValue, "", RaisedBB);
BinOpInst = BinaryOperator::CreateAnd(DestValue, LoadValue);
} break;
case X86::PORrm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
BinOpInst = BinaryOperator::CreateOr(DestValue, LoadValue);
} break;
case X86::PXORrm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
BinOpInst = BinaryOperator::CreateXor(DestValue, LoadValue);
} break;
case X86::SBB16rm:
case X86::SBB32rm:
case X86::SBB64rm:
case X86::SBB8rm: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
auto CFValue = getRegOrArgValue(EFLAGS::CF, MI.getParent()->getNumber());
assert(CFValue && "Expected CF to be set for sbb instruction");

Expand All @@ -1768,6 +1784,7 @@ bool X86MachineInstructionRaiser::raiseBinaryOpMemToRegInstr(
case X86::SQRTSDm_Int:
case X86::SQRTSSm:
case X86::SQRTSSm_Int: {
assert(DestValue != nullptr && "Encountered instruction with undefined register");
LLVMContext &Ctx(MF.getFunction().getContext());

Type *InstrTy = getRaisedValues()->getSSEInstructionType(MI, Ctx);
Expand Down
35 changes: 35 additions & 0 deletions test/asm_test/X86/raise-imul-rmi.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// REQUIRES: x86_64-linux
// RUN: clang -O0 -o %t %s
// RUN: llvm-mctoll -d -I /usr/include/stdio.h %t
// RUN: clang -o %t-dis %t-dis.ll
// RUN: %t-dis 2>&1 | FileCheck %s
// CHECK: 4
// CHECK-EMPTY

.text
.intel_syntax noprefix
.file "raise-xor-ri.s"


.globl main # -- Begin function main
.p2align 4, 0x90
.type main,@function
main: # @main
sub rsp, 4
mov dword ptr [rsp], 2
# destination register is a register with an undefined value
imul eax, dword ptr [rsp], 2
mov esi, eax
movabs rdi, offset .L.str
mov al, 0
call printf

add rsp, 4
mov eax, 0
ret

.type .L.str,@object # @.str
.section .rodata.str1.1,"aMS",@progbits,1
.L.str:
.asciz "%d\n"
.size .L.str, 4

0 comments on commit 91c5bfa

Please sign in to comment.