forked from OSchip/llvm-project
Assembly and Bitcode support for unsigned/signed overflow flags and
exact sdiv flags. llvm-svn: 76475
This commit is contained in:
parent
94e12450aa
commit
0ebd69614c
|
@ -171,6 +171,18 @@ namespace bitc {
|
|||
BINOP_XOR = 12
|
||||
};
|
||||
|
||||
/// OverflowingBinaryOperatorOptionalFlags - Flags for serializing
|
||||
/// OverflowingBinaryOperator's SubclassOptionalData contents.
|
||||
enum OverflowingBinaryOperatorOptionalFlags {
|
||||
OBO_NO_UNSIGNED_OVERFLOW = 0,
|
||||
OBO_NO_SIGNED_OVERFLOW = 1
|
||||
};
|
||||
|
||||
/// SDivOperatorOptionalFlags - Flags for serializing SDivOperator's
|
||||
/// SubclassOptionalData contents.
|
||||
enum SDivOperatorOptionalFlags {
|
||||
SDIV_EXACT = 0
|
||||
};
|
||||
|
||||
// The function body block (FUNCTION_BLOCK_ID) describes function bodies. It
|
||||
// can contain a constant block (CONSTANTS_BLOCK_ID).
|
||||
|
|
|
@ -501,6 +501,9 @@ lltok::Kind LLLexer::LexIdentifier() {
|
|||
KEYWORD(deplibs);
|
||||
KEYWORD(datalayout);
|
||||
KEYWORD(volatile);
|
||||
KEYWORD(signed);
|
||||
KEYWORD(unsigned);
|
||||
KEYWORD(exact);
|
||||
KEYWORD(align);
|
||||
KEYWORD(addrspace);
|
||||
KEYWORD(section);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/MDNode.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Operator.h"
|
||||
#include "llvm/ValueSymbolTable.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
|
@ -2041,6 +2042,49 @@ bool LLParser::ParseValID(ValID &ID) {
|
|||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
case lltok::kw_signed: {
|
||||
Lex.Lex();
|
||||
bool AlsoUnsigned = EatIfPresent(lltok::kw_unsigned);
|
||||
if (Lex.getKind() != lltok::kw_add &&
|
||||
Lex.getKind() != lltok::kw_sub &&
|
||||
Lex.getKind() != lltok::kw_mul)
|
||||
return TokError("expected 'add', 'sub', or 'mul'");
|
||||
bool Result = LLParser::ParseValID(ID);
|
||||
if (!Result) {
|
||||
cast<OverflowingBinaryOperator>(ID.ConstantVal)
|
||||
->setHasNoSignedOverflow(true);
|
||||
if (AlsoUnsigned)
|
||||
cast<OverflowingBinaryOperator>(ID.ConstantVal)
|
||||
->setHasNoUnsignedOverflow(true);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
case lltok::kw_unsigned: {
|
||||
Lex.Lex();
|
||||
bool AlsoSigned = EatIfPresent(lltok::kw_signed);
|
||||
if (Lex.getKind() != lltok::kw_add &&
|
||||
Lex.getKind() != lltok::kw_sub &&
|
||||
Lex.getKind() != lltok::kw_mul)
|
||||
return TokError("expected 'add', 'sub', or 'mul'");
|
||||
bool Result = LLParser::ParseValID(ID);
|
||||
if (!Result) {
|
||||
cast<OverflowingBinaryOperator>(ID.ConstantVal)
|
||||
->setHasNoUnsignedOverflow(true);
|
||||
if (AlsoSigned)
|
||||
cast<OverflowingBinaryOperator>(ID.ConstantVal)
|
||||
->setHasNoSignedOverflow(true);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
case lltok::kw_exact: {
|
||||
Lex.Lex();
|
||||
if (Lex.getKind() != lltok::kw_sdiv)
|
||||
return TokError("expected 'sdiv'");
|
||||
bool Result = LLParser::ParseValID(ID);
|
||||
if (!Result)
|
||||
cast<SDivOperator>(ID.ConstantVal)->setIsExact(true);
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
Lex.Lex();
|
||||
|
@ -2558,6 +2602,50 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
|
|||
return ParseStore(Inst, PFS, true);
|
||||
else
|
||||
return TokError("expected 'load' or 'store'");
|
||||
case lltok::kw_signed: {
|
||||
bool AlsoUnsigned = EatIfPresent(lltok::kw_unsigned);
|
||||
if (Lex.getKind() == lltok::kw_add ||
|
||||
Lex.getKind() == lltok::kw_sub ||
|
||||
Lex.getKind() == lltok::kw_mul) {
|
||||
Lex.Lex();
|
||||
KeywordVal = Lex.getUIntVal();
|
||||
bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 0);
|
||||
if (!Result) {
|
||||
cast<OverflowingBinaryOperator>(Inst)->setHasNoSignedOverflow(true);
|
||||
if (AlsoUnsigned)
|
||||
cast<OverflowingBinaryOperator>(Inst)->setHasNoUnsignedOverflow(true);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
return TokError("expected 'add', 'sub', or 'mul'");
|
||||
}
|
||||
case lltok::kw_unsigned: {
|
||||
bool AlsoSigned = EatIfPresent(lltok::kw_signed);
|
||||
if (Lex.getKind() == lltok::kw_add ||
|
||||
Lex.getKind() == lltok::kw_sub ||
|
||||
Lex.getKind() == lltok::kw_mul) {
|
||||
Lex.Lex();
|
||||
KeywordVal = Lex.getUIntVal();
|
||||
bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
|
||||
if (!Result) {
|
||||
cast<OverflowingBinaryOperator>(Inst)->setHasNoUnsignedOverflow(true);
|
||||
if (AlsoSigned)
|
||||
cast<OverflowingBinaryOperator>(Inst)->setHasNoSignedOverflow(true);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
return TokError("expected 'add', 'sub', or 'mul'");
|
||||
}
|
||||
case lltok::kw_exact:
|
||||
if (Lex.getKind() == lltok::kw_sdiv) {
|
||||
Lex.Lex();
|
||||
KeywordVal = Lex.getUIntVal();
|
||||
bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
|
||||
if (!Result)
|
||||
cast<SDivOperator>(Inst)->setIsExact(true);
|
||||
return Result;
|
||||
}
|
||||
return TokError("expected 'udiv'");
|
||||
case lltok::kw_getresult: return ParseGetResult(Inst, PFS);
|
||||
case lltok::kw_getelementptr: return ParseGetElementPtr(Inst, PFS);
|
||||
case lltok::kw_extractvalue: return ParseExtractValue(Inst, PFS);
|
||||
|
|
|
@ -51,6 +51,9 @@ namespace lltok {
|
|||
kw_deplibs,
|
||||
kw_datalayout,
|
||||
kw_volatile,
|
||||
kw_signed,
|
||||
kw_unsigned,
|
||||
kw_exact,
|
||||
kw_align,
|
||||
kw_addrspace,
|
||||
kw_section,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/MDNode.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Operator.h"
|
||||
#include "llvm/AutoUpgrade.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
@ -747,6 +748,18 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() {
|
|||
return false;
|
||||
}
|
||||
|
||||
static void SetOptimizationFlags(Value *V, uint64_t Flags) {
|
||||
if (OverflowingBinaryOperator *OBO =
|
||||
dyn_cast<OverflowingBinaryOperator>(V)) {
|
||||
if (Flags & (1 << bitc::OBO_NO_SIGNED_OVERFLOW))
|
||||
OBO->setHasNoSignedOverflow(true);
|
||||
if (Flags & (1 << bitc::OBO_NO_UNSIGNED_OVERFLOW))
|
||||
OBO->setHasNoUnsignedOverflow(true);
|
||||
} else if (SDivOperator *Div = dyn_cast<SDivOperator>(V)) {
|
||||
if (Flags & (1 << bitc::SDIV_EXACT))
|
||||
Div->setIsExact(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool BitcodeReader::ParseConstants() {
|
||||
if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
|
||||
|
@ -778,7 +791,8 @@ bool BitcodeReader::ParseConstants() {
|
|||
// Read a record.
|
||||
Record.clear();
|
||||
Value *V = 0;
|
||||
switch (Stream.ReadRecord(Code, Record)) {
|
||||
unsigned BitCode = Stream.ReadRecord(Code, Record);
|
||||
switch (BitCode) {
|
||||
default: // Default behavior: unknown constant
|
||||
case bitc::CST_CODE_UNDEF: // UNDEF
|
||||
V = Context.getUndef(CurTy);
|
||||
|
@ -899,6 +913,8 @@ bool BitcodeReader::ParseConstants() {
|
|||
Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
|
||||
V = Context.getConstantExpr(Opc, LHS, RHS);
|
||||
}
|
||||
if (Record.size() >= 4)
|
||||
SetOptimizationFlags(V, Record[3]);
|
||||
break;
|
||||
}
|
||||
case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval]
|
||||
|
@ -1451,7 +1467,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
|||
// Read a record.
|
||||
Record.clear();
|
||||
Instruction *I = 0;
|
||||
switch (Stream.ReadRecord(Code, Record)) {
|
||||
unsigned BitCode = Stream.ReadRecord(Code, Record);
|
||||
switch (BitCode) {
|
||||
default: // Default behavior: reject
|
||||
return Error("Unknown instruction");
|
||||
case bitc::FUNC_CODE_DECLAREBLOCKS: // DECLAREBLOCKS: [nblocks]
|
||||
|
@ -1469,12 +1486,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
|||
Value *LHS, *RHS;
|
||||
if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
|
||||
getValue(Record, OpNum, LHS->getType(), RHS) ||
|
||||
OpNum+1 != Record.size())
|
||||
OpNum+1 > Record.size())
|
||||
return Error("Invalid BINOP record");
|
||||
|
||||
int Opc = GetDecodedBinaryOpcode(Record[OpNum], LHS->getType());
|
||||
int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
|
||||
if (Opc == -1) return Error("Invalid BINOP record");
|
||||
I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
|
||||
if (OpNum < Record.size())
|
||||
SetOptimizationFlags(I, Record[3]);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc]
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "llvm/Instructions.h"
|
||||
#include "llvm/MDNode.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Operator.h"
|
||||
#include "llvm/TypeSymbolTable.h"
|
||||
#include "llvm/ValueSymbolTable.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
@ -50,6 +51,7 @@ enum {
|
|||
// FUNCTION_BLOCK abbrev id's.
|
||||
FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
|
||||
FUNCTION_INST_BINOP_ABBREV,
|
||||
FUNCTION_INST_BINOP_FLAGS_ABBREV,
|
||||
FUNCTION_INST_CAST_ABBREV,
|
||||
FUNCTION_INST_RET_VOID_ABBREV,
|
||||
FUNCTION_INST_RET_VAL_ABBREV,
|
||||
|
@ -454,6 +456,22 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
|
|||
}
|
||||
}
|
||||
|
||||
static uint64_t GetOptimizationFlags(const Value *V) {
|
||||
uint64_t Flags = 0;
|
||||
|
||||
if (const OverflowingBinaryOperator *OBO =
|
||||
dyn_cast<OverflowingBinaryOperator>(V)) {
|
||||
if (OBO->hasNoSignedOverflow())
|
||||
Flags |= 1 << bitc::OBO_NO_SIGNED_OVERFLOW;
|
||||
if (OBO->hasNoUnsignedOverflow())
|
||||
Flags |= 1 << bitc::OBO_NO_UNSIGNED_OVERFLOW;
|
||||
} else if (const SDivOperator *Div = dyn_cast<SDivOperator>(V)) {
|
||||
if (Div->isExact())
|
||||
Flags |= 1 << bitc::SDIV_EXACT;
|
||||
}
|
||||
|
||||
return Flags;
|
||||
}
|
||||
|
||||
static void WriteConstants(unsigned FirstVal, unsigned LastVal,
|
||||
const ValueEnumerator &VE,
|
||||
|
@ -641,6 +659,9 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
|
|||
Record.push_back(GetEncodedBinaryOpcode(CE->getOpcode()));
|
||||
Record.push_back(VE.getValueID(C->getOperand(0)));
|
||||
Record.push_back(VE.getValueID(C->getOperand(1)));
|
||||
uint64_t Flags = GetOptimizationFlags(CE);
|
||||
if (Flags != 0)
|
||||
Record.push_back(Flags);
|
||||
}
|
||||
break;
|
||||
case Instruction::GetElementPtr:
|
||||
|
@ -778,6 +799,12 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
|||
AbbrevToUse = FUNCTION_INST_BINOP_ABBREV;
|
||||
Vals.push_back(VE.getValueID(I.getOperand(1)));
|
||||
Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode()));
|
||||
uint64_t Flags = GetOptimizationFlags(&I);
|
||||
if (Flags != 0) {
|
||||
if (AbbrevToUse == FUNCTION_INST_BINOP_ABBREV)
|
||||
AbbrevToUse = FUNCTION_INST_BINOP_FLAGS_ABBREV;
|
||||
Vals.push_back(Flags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1225,6 +1252,17 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
|
|||
Abbv) != FUNCTION_INST_BINOP_ABBREV)
|
||||
llvm_unreachable("Unexpected abbrev ordering!");
|
||||
}
|
||||
{ // INST_BINOP_FLAGS abbrev for FUNCTION_BLOCK.
|
||||
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
||||
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // flags
|
||||
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
|
||||
Abbv) != FUNCTION_INST_BINOP_FLAGS_ABBREV)
|
||||
llvm_unreachable("Unexpected abbrev ordering!");
|
||||
}
|
||||
{ // INST_CAST abbrev for FUNCTION_BLOCK.
|
||||
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
||||
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST));
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "llvm/InlineAsm.h"
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Operator.h"
|
||||
#include "llvm/MDNode.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ValueSymbolTable.h"
|
||||
|
@ -851,6 +852,19 @@ static void WriteMDNodes(raw_ostream &Out, TypePrinting &TypePrinter,
|
|||
}
|
||||
}
|
||||
|
||||
static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
|
||||
if (const OverflowingBinaryOperator *OBO =
|
||||
dyn_cast<OverflowingBinaryOperator>(U)) {
|
||||
if (OBO->hasNoUnsignedOverflow())
|
||||
Out << "unsigned ";
|
||||
if (OBO->hasNoSignedOverflow())
|
||||
Out << "signed ";
|
||||
} else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) {
|
||||
if (Div->isExact())
|
||||
Out << "exact ";
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
|
||||
TypePrinting &TypePrinter, SlotTracker *Machine) {
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
|
||||
|
@ -1062,6 +1076,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
|
|||
}
|
||||
|
||||
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
|
||||
WriteOptimizationInfo(Out, CE);
|
||||
Out << CE->getOpcodeName();
|
||||
if (CE->isCompare())
|
||||
Out << ' ' << getPredicateText(CE->getPredicate());
|
||||
|
@ -1682,6 +1697,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
|
|||
Out << "tail ";
|
||||
}
|
||||
|
||||
// Print out optimization information.
|
||||
WriteOptimizationInfo(Out, &I);
|
||||
|
||||
// Print out the opcode...
|
||||
Out << I.getOpcodeName();
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
||||
|
||||
@addr = external global i64
|
||||
|
||||
define i64 @add_plain_ce() {
|
||||
; CHECK: ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @sub_plain_ce() {
|
||||
; CHECK: ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @mul_plain_ce() {
|
||||
; CHECK: ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @sdiv_plain_ce() {
|
||||
; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
||||
|
||||
@addr = external global i64
|
||||
|
||||
define i64 @add_both_reversed_ce() {
|
||||
; CHECK: ret i64 unsigned signed add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 signed unsigned add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @sub_both_reversed_ce() {
|
||||
; CHECK: ret i64 unsigned signed sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 signed unsigned sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @mul_both_reversed_ce() {
|
||||
; CHECK: ret i64 unsigned signed mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 signed unsigned mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
||||
|
||||
@addr = external global i64
|
||||
|
||||
define i64 @add_signed_ce() {
|
||||
; CHECK: ret i64 signed add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 signed add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @sub_signed_ce() {
|
||||
; CHECK: ret i64 signed sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 signed sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @mul_signed_ce() {
|
||||
; CHECK: ret i64 signed mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 signed mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
||||
|
||||
@addr = external global i64
|
||||
|
||||
define i64 @add_unsigned_ce() {
|
||||
; CHECK: ret i64 unsigned add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 unsigned add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @sub_unsigned_ce() {
|
||||
; CHECK: ret i64 unsigned sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 unsigned sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @mul_unsigned_ce() {
|
||||
; CHECK: ret i64 unsigned mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 unsigned mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
||||
|
||||
@addr = external global i64
|
||||
|
||||
define i64 @add_signed(i64 %x, i64 %y) {
|
||||
; CHECK: %z = signed add i64 %x, %y
|
||||
%z = signed add i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @sub_signed(i64 %x, i64 %y) {
|
||||
; CHECK: %z = signed sub i64 %x, %y
|
||||
%z = signed sub i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @mul_signed(i64 %x, i64 %y) {
|
||||
; CHECK: %z = signed mul i64 %x, %y
|
||||
%z = signed mul i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @add_unsigned(i64 %x, i64 %y) {
|
||||
; CHECK: %z = unsigned add i64 %x, %y
|
||||
%z = unsigned add i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @sub_unsigned(i64 %x, i64 %y) {
|
||||
; CHECK: %z = unsigned sub i64 %x, %y
|
||||
%z = unsigned sub i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @mul_unsigned(i64 %x, i64 %y) {
|
||||
; CHECK: %z = unsigned mul i64 %x, %y
|
||||
%z = unsigned mul i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @add_plain(i64 %x, i64 %y) {
|
||||
; CHECK: %z = add i64 %x, %y
|
||||
%z = add i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @sub_plain(i64 %x, i64 %y) {
|
||||
; CHECK: %z = sub i64 %x, %y
|
||||
%z = sub i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @mul_plain(i64 %x, i64 %y) {
|
||||
; CHECK: %z = mul i64 %x, %y
|
||||
%z = mul i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @add_both(i64 %x, i64 %y) {
|
||||
; CHECK: %z = unsigned signed add i64 %x, %y
|
||||
%z = unsigned signed add i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @sub_both(i64 %x, i64 %y) {
|
||||
; CHECK: %z = unsigned signed sub i64 %x, %y
|
||||
%z = unsigned signed sub i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @mul_both(i64 %x, i64 %y) {
|
||||
; CHECK: %z = unsigned signed mul i64 %x, %y
|
||||
%z = unsigned signed mul i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @add_both_reversed(i64 %x, i64 %y) {
|
||||
; CHECK: %z = unsigned signed add i64 %x, %y
|
||||
%z = signed unsigned add i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @sub_both_reversed(i64 %x, i64 %y) {
|
||||
; CHECK: %z = unsigned signed sub i64 %x, %y
|
||||
%z = signed unsigned sub i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @mul_both_reversed(i64 %x, i64 %y) {
|
||||
; CHECK: %z = unsigned signed mul i64 %x, %y
|
||||
%z = signed unsigned mul i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @sdiv_exact(i64 %x, i64 %y) {
|
||||
; CHECK: %z = exact sdiv i64 %x, %y
|
||||
%z = exact sdiv i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @sdiv_plain(i64 %x, i64 %y) {
|
||||
; CHECK: %z = sdiv i64 %x, %y
|
||||
%z = sdiv i64 %x, %y
|
||||
ret i64 %z
|
||||
}
|
||||
|
||||
define i64 @add_both_ce() {
|
||||
; CHECK: ret i64 unsigned signed add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 signed unsigned add (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @sub_both_ce() {
|
||||
; CHECK: ret i64 unsigned signed sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 signed unsigned sub (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @mul_both_ce() {
|
||||
; CHECK: ret i64 unsigned signed mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 unsigned signed mul (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
||||
|
||||
define i64 @sdiv_exact_ce() {
|
||||
; CHECK: ret i64 exact sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
ret i64 exact sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
|
||||
}
|
Loading…
Reference in New Issue