Commit b36757e1 by Jim Stichnoth

Subzero: Fix nondeterministic behavior in constant pool creation.

This issue was discovered as the result of a spurious "make check-lit" failure in undef.ll. The problem is that constant pool label strings depend on the order the constants are created, and this order can be different with multithreaded translation. Even -filetype=obj is affected by this, because the label string is put into the ELF .o file. This means that different runs of Subzero on the same input could potentially produce slightly different output. The solution is to base the label name on the actual value of the constant. We do this by using the hex representation of the constant, rather than the sequence number of the constant within the pool. This actually simplifies things a bit, as we no longer need to track the sequence number. In addition, for floating-point constant labels in asm-verbose mode, include a human-readable rendering of the value in the label name. BUG= none R=kschimpf@google.com Review URL: https://codereview.chromium.org/1386593004 .
parent 9a63babb
......@@ -526,7 +526,7 @@ template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) {
auto Const = llvm::cast<ConstType>(C);
std::string SymBuffer;
llvm::raw_string_ostream SymStrBuf(SymBuffer);
Const->emitPoolLabel(SymStrBuf);
Const->emitPoolLabel(SymStrBuf, &Ctx);
std::string &SymName = SymStrBuf.str();
SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section,
OffsetInSection, SymbolSize);
......
......@@ -43,7 +43,7 @@ IceString AssemblerFixup::symbol(const GlobalContext *Ctx) const {
// NOTE: currently only float/doubles are put into constant pools. In the
// future we may put integers as well.
assert(llvm::isa<ConstantFloat>(C) || llvm::isa<ConstantDouble>(C));
C->emitPoolLabel(Str);
C->emitPoolLabel(Str, Ctx);
}
return Str.str();
}
......
......@@ -130,7 +130,7 @@ public:
auto Iter = Pool.find(Key);
if (Iter != Pool.end())
return Iter->second;
ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++);
ValueType *Result = ValueType::create(Ctx, Ty, Key);
Pool[Key] = Result;
return Result;
}
......@@ -157,7 +157,6 @@ private:
std::unordered_map<KeyType, ValueType *, std::hash<KeyType>,
KeyCompare<KeyType>>;
ContainerType Pool;
uint32_t NextPoolID = 0;
};
// UndefPool maps ICE types to the corresponding ConstantUndef values.
......@@ -170,12 +169,11 @@ public:
ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) {
if (Pool[Ty] == nullptr)
Pool[Ty] = ConstantUndef::create(Ctx, Ty, NextPoolID++);
Pool[Ty] = ConstantUndef::create(Ctx, Ty);
return Pool[Ty];
}
private:
uint32_t NextPoolID = 0;
std::vector<ConstantUndef *> Pool;
};
......
......@@ -23,6 +23,8 @@
#include "IceGlobalContext.h"
#include "IceTypes.h"
#include "llvm/Support/Format.h"
namespace Ice {
class Operand {
......@@ -115,9 +117,11 @@ class Constant : public Operand {
Constant &operator=(const Constant &) = delete;
public:
void emitPoolLabel(Ostream &Str) const {
Str << ".L$" << getType() << "$" << PoolEntryID;
}
virtual void emitPoolLabel(Ostream &Str, const GlobalContext *Ctx) const {
(void)Str;
(void)Ctx;
llvm::report_fatal_error("emitPoolLabel not defined for type");
};
void emit(const Cfg *Func) const override { emit(Func->getTarget()); }
virtual void emit(TargetLowering *Target) const = 0;
......@@ -139,15 +143,11 @@ public:
bool getShouldBePooled() const { return shouldBePooled; }
protected:
Constant(OperandKind Kind, Type Ty, uint32_t PoolEntryID)
: Operand(Kind, Ty), PoolEntryID(PoolEntryID), shouldBePooled(false) {
Constant(OperandKind Kind, Type Ty)
: Operand(Kind, Ty), shouldBePooled(false) {
Vars = nullptr;
NumVars = 0;
}
/// PoolEntryID is an integer that uniquely identifies the constant within its
/// constant pool. It is used for building the constant pool in the object
/// code and for referencing its entries.
const uint32_t PoolEntryID;
/// Whether we should pool this constant. Usually Float/Double and pooled
/// Integers should be flagged true.
bool shouldBePooled;
......@@ -163,14 +163,42 @@ class ConstantPrimitive : public Constant {
public:
using PrimType = T;
static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, PrimType Value,
uint32_t PoolEntryID) {
static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty,
PrimType Value) {
assert(!Ctx->isIRGenerationDisabled() &&
"Attempt to build primitive constant when IR generation disabled");
return new (Ctx->allocate<ConstantPrimitive>())
ConstantPrimitive(Ty, Value, PoolEntryID);
ConstantPrimitive(Ty, Value);
}
PrimType getValue() const { return Value; }
void emitPoolLabel(Ostream &Str, const GlobalContext *Ctx) const final {
Str << ".L$" << getType() << "$";
// Print hex characters byte by byte, starting from the most significant
// byte. NOTE: This ordering assumes Subzero runs on a little-endian
// platform. That means the possibility of different label names depending
// on the endian-ness of the platform where Subzero runs.
for (unsigned i = 0; i < sizeof(Value); ++i) {
constexpr unsigned HexWidthChars = 2;
unsigned Offset = sizeof(Value) - 1 - i;
Str << llvm::format_hex_no_prefix(
*(Offset + (const unsigned char *)&Value), HexWidthChars);
}
// For a floating-point value in DecorateAsm mode, also append the value in
// human-readable sprintf form, changing '+' to 'p' and '-' to 'm' to
// maintain valid asm labels.
if (std::is_floating_point<PrimType>::value && !BuildDefs::minimal() &&
Ctx->getFlags().getDecorateAsm()) {
char Buf[30];
snprintf(Buf, llvm::array_lengthof(Buf), "$%g", (double)Value);
for (unsigned i = 0; i < llvm::array_lengthof(Buf) && Buf[i]; ++i) {
if (Buf[i] == '-')
Buf[i] = 'm';
else if (Buf[i] == '+')
Buf[i] = 'p';
}
Str << Buf;
}
}
using Constant::emit;
void emit(TargetLowering *Target) const final;
using Constant::dump;
......@@ -189,8 +217,7 @@ public:
}
private:
ConstantPrimitive(Type Ty, PrimType Value, uint32_t PoolEntryID)
: Constant(K, Ty, PoolEntryID), Value(Value) {}
ConstantPrimitive(Type Ty, PrimType Value) : Constant(K, Ty), Value(Value) {}
const PrimType Value;
};
......@@ -250,12 +277,11 @@ class ConstantRelocatable : public Constant {
public:
static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty,
const RelocatableTuple &Tuple,
uint32_t PoolEntryID) {
const RelocatableTuple &Tuple) {
assert(!Ctx->isIRGenerationDisabled() &&
"Attempt to build relocatable constant when IR generation disabled");
return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable(
Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling, PoolEntryID);
Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling);
}
RelocOffsetT getOffset() const { return Offset; }
......@@ -275,9 +301,9 @@ public:
private:
ConstantRelocatable(Type Ty, RelocOffsetT Offset, const IceString &Name,
bool SuppressMangling, uint32_t PoolEntryID)
: Constant(kConstRelocatable, Ty, PoolEntryID), Offset(Offset),
Name(Name), SuppressMangling(SuppressMangling) {}
bool SuppressMangling)
: Constant(kConstRelocatable, Ty), Offset(Offset), Name(Name),
SuppressMangling(SuppressMangling) {}
const RelocOffsetT Offset; /// fixed offset to add
const IceString Name; /// optional for debug/dump
bool SuppressMangling;
......@@ -292,11 +318,10 @@ class ConstantUndef : public Constant {
ConstantUndef &operator=(const ConstantUndef &) = delete;
public:
static ConstantUndef *create(GlobalContext *Ctx, Type Ty,
uint32_t PoolEntryID) {
static ConstantUndef *create(GlobalContext *Ctx, Type Ty) {
assert(!Ctx->isIRGenerationDisabled() &&
"Attempt to build undefined constant when IR generation disabled");
return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty, PoolEntryID);
return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty);
}
using Constant::emit;
......@@ -312,8 +337,7 @@ public:
}
private:
ConstantUndef(Type Ty, uint32_t PoolEntryID)
: Constant(kConstUndef, Ty, PoolEntryID) {}
ConstantUndef(Type Ty) : Constant(kConstUndef, Ty) {}
};
/// RegWeight is a wrapper for a uint32_t weight value, with a special value
......
......@@ -3150,7 +3150,7 @@ Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed,
// loading to SREG.
std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer);
llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx);
llvm::cast<Constant>(From)->setShouldBePooled(true);
Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
Variable *BaseReg = makeReg(getPointerType());
......@@ -3358,10 +3358,10 @@ const char ConstantPoolEmitterTraits<double>::TypeName[] = "f64";
template <typename T>
void emitConstant(
Ostream &Str,
Ostream &Str, const GlobalContext *Ctx,
const typename ConstantPoolEmitterTraits<T>::ConstantType *Const) {
using Traits = ConstantPoolEmitterTraits<T>;
Const->emitPoolLabel(Str);
Const->emitPoolLabel(Str, Ctx);
Str << ":\n\t" << Traits::AsmTag << "\t0x";
T Value = Const->getValue();
Str.write_hex(Traits::bitcastToUint64(Value));
......@@ -3394,7 +3394,7 @@ template <typename T> void emitConstantPool(GlobalContext *Ctx) {
continue;
}
emitConstant<T>(Str, llvm::dyn_cast<typename Traits::ConstantType>(C));
emitConstant<T>(Str, Ctx, llvm::dyn_cast<typename Traits::ConstantType>(C));
}
}
} // end of anonymous namespace
......
......@@ -255,13 +255,13 @@ protected:
Context.insert(InstARM32Ldr::create(Func, Dest, Addr, Pred));
}
void _ldrex(Variable *Dest, OperandARM32Mem *Addr,
CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Ldrex::create(Func, Dest, Addr, Pred));
if (auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest)) {
Context.insert(InstFakeDef::create(Func, Dest64->getLo(), Dest));
Context.insert(InstFakeDef::create(Func, Dest64->getHi(), Dest));
}
}
CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Ldrex::create(Func, Dest, Addr, Pred));
if (auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest)) {
Context.insert(InstFakeDef::create(Func, Dest64->getLo(), Dest));
Context.insert(InstFakeDef::create(Func, Dest64->getHi(), Dest));
}
}
void _lsl(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Lsl::create(Func, Dest, Src0, Src1, Pred));
......
......@@ -757,7 +757,7 @@ void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) {
assert(CharsPrinted >= 0 &&
(size_t)CharsPrinted < llvm::array_lengthof(buf));
(void)CharsPrinted; // avoid warnings if asserts are disabled
Const->emitPoolLabel(Str);
Const->emitPoolLabel(Str, Ctx);
Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
<< Value << "\n";
}
......
......@@ -773,7 +773,7 @@ void TargetDataX8664::emitConstantPool(GlobalContext *Ctx) {
assert(CharsPrinted >= 0 &&
(size_t)CharsPrinted < llvm::array_lengthof(buf));
(void)CharsPrinted; // avoid warnings if asserts are disabled
Const->emitPoolLabel(Str);
Const->emitPoolLabel(Str, Ctx);
Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
<< Value << "\n";
}
......
......@@ -5096,7 +5096,7 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
Variable *Base = nullptr;
std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer);
llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx);
llvm::cast<Constant>(From)->setShouldBePooled(true);
Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
From = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
......@@ -5293,7 +5293,7 @@ void TargetX86Base<Machine>::emit(const ConstantFloat *C) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
C->emitPoolLabel(Str);
C->emitPoolLabel(Str, Ctx);
}
template <class Machine>
......@@ -5301,7 +5301,7 @@ void TargetX86Base<Machine>::emit(const ConstantDouble *C) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
C->emitPoolLabel(Str);
C->emitPoolLabel(Str, Ctx);
}
template <class Machine>
......@@ -5367,7 +5367,7 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
Variable *Reg = makeReg(Immediate->getType(), RegNum);
IceString Label;
llvm::raw_string_ostream Label_stream(Label);
Immediate->emitPoolLabel(Label_stream);
Immediate->emitPoolLabel(Label_stream, Ctx);
const RelocOffsetT Offset = 0;
const bool SuppressMangling = true;
Constant *Symbol =
......@@ -5463,7 +5463,7 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(
Variable *RegTemp = makeReg(IceType_i32);
IceString Label;
llvm::raw_string_ostream Label_stream(Label);
MemOperand->getOffset()->emitPoolLabel(Label_stream);
MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx);
MemOperand->getOffset()->setShouldBePooled(true);
const RelocOffsetT SymOffset = 0;
bool SuppressMangling = true;
......
......@@ -49,8 +49,8 @@ entry:
ret i64 %v0
}
; CHECK-LABEL: cast_d2ll_const
; CHECK: mov e{{..}},DWORD PTR ds:0x0 {{.*}} .L$double$0
; CHECK: mov e{{..}},DWORD PTR ds:0x4 {{.*}} .L$double$0
; CHECK: mov e{{..}},DWORD PTR ds:0x0 {{.*}} .L$double$0012345678901234
; CHECK: mov e{{..}},DWORD PTR ds:0x4 {{.*}} .L$double$0012345678901234
; ARM32-LABEL: cast_d2ll_const
; ARM32-DAG: movw [[ADDR:r[0-9]+]], #:lower16:.L$
; ARM32-DAG: movt [[ADDR]], #:upper16:.L$
......
......@@ -55,8 +55,8 @@ entry:
ret float %f
}
; TEXT-RELOCS-LABEL: returnFloatConst
; TEXT-RELOCS: movss {{.*}} R_386_32 .L$float$0
; TEXT-RELOCS: addss {{.*}} R_386_32 .L$float$1
; TEXT-RELOCS: movss {{.*}} R_386_32 .L$float$80000000
; TEXT-RELOCS: addss {{.*}} R_386_32 .L$float$3f9d70a0
define internal double @returnDoubleConst() {
entry:
......@@ -65,9 +65,9 @@ entry:
ret double %d2
}
; TEXT-RELOCS-LABEL: returnDoubleConst
; TEXT-RELOCS: movsd {{.*}} R_386_32 .L$double$0
; TEXT-RELOCS: addsd {{.*}} R_386_32 .L$double$1
; TEXT-RELOCS: addsd {{.*}} R_386_32 .L$double$2
; TEXT-RELOCS: movsd {{.*}} R_386_32 .L$double$ffffffffffffffff
; TEXT-RELOCS: addsd {{.*}} R_386_32 .L$double$fff7ffffffffffff
; TEXT-RELOCS: addsd {{.*}} R_386_32 .L$double$fff8000000000003
; Test intrinsics that call out to external functions.
define internal void @test_memcpy(i32 %iptr_dst, i32 %len) {
......@@ -383,11 +383,11 @@ define void @_start(i32) {
; CHECK: Relocations [
; CHECK: Section ({{[0-9]+}}) .rel.text {
; CHECK: 0x4 R_386_32 .L$float$0 0x0
; CHECK: 0xC R_386_32 .L$float$1 0x0
; CHECK: 0x24 R_386_32 .L$double$0 0x0
; CHECK: 0x2C R_386_32 .L$double$1 0x0
; CHECK: 0x34 R_386_32 .L$double$2 0x0
; CHECK: 0x4 R_386_32 .L$float$80000000 0x0
; CHECK: 0xC R_386_32 .L$float$3f9d70a0 0x0
; CHECK: 0x24 R_386_32 .L$double$ffffffffffffffff 0x0
; CHECK: 0x2C R_386_32 .L$double$fff7ffffffffffff 0x0
; CHECK: 0x34 R_386_32 .L$double$fff8000000000003 0x0
; CHECK: 0x{{.*}} R_386_PC32 memcpy
; CHECK: 0x{{.*}} R_386_PC32 memset
; CHECK: 0x{{.*}} R_386_PC32 external_foo
......@@ -419,8 +419,8 @@ define void @_start(i32) {
; CHECK-NEXT: Section: Undefined (0x0)
; CHECK-NEXT: }
; CHECK: Symbol {
; CHECK: Name: .L$double$0
; CHECK-NEXT: Value: 0x10
; CHECK: Name: .L$double$fff8000000000003
; CHECK-NEXT: Value: 0x8
; CHECK-NEXT: Size: 0
; CHECK-NEXT: Binding: Local (0x0)
; CHECK-NEXT: Type: None (0x0)
......@@ -428,8 +428,8 @@ define void @_start(i32) {
; CHECK-NEXT: Section: .rodata.cst8
; CHECK-NEXT: }
; CHECK: Symbol {
; CHECK: Name: .L$double$2
; CHECK-NEXT: Value: 0x8
; CHECK: Name: .L$double$ffffffffffffffff
; CHECK-NEXT: Value: 0x10
; CHECK-NEXT: Size: 0
; CHECK-NEXT: Binding: Local (0x0)
; CHECK-NEXT: Type: None (0x0)
......@@ -437,8 +437,8 @@ define void @_start(i32) {
; CHECK-NEXT: Section: .rodata.cst8
; CHECK-NEXT: }
; CHECK: Symbol {
; CHECK: Name: .L$float$0
; CHECK-NEXT: Value: 0x4
; CHECK: Name: .L$float$3f9d70a0
; CHECK-NEXT: Value: 0x0
; CHECK-NEXT: Size: 0
; CHECK-NEXT: Binding: Local (0x0)
; CHECK-NEXT: Type: None (0x0)
......@@ -446,8 +446,8 @@ define void @_start(i32) {
; CHECK-NEXT: Section: .rodata.cst4
; CHECK-NEXT: }
; CHECK: Symbol {
; CHECK: Name: .L$float$1
; CHECK-NEXT: Value: 0x0
; CHECK: Name: .L$float$80000000
; CHECK-NEXT: Value: 0x4
; CHECK-NEXT: Size: 0
; CHECK-NEXT: Binding: Local (0x0)
; CHECK-NEXT: Type: None (0x0)
......
......@@ -33,7 +33,7 @@ entry:
; BLINDINGOM1-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x669c41aa{{[]]}}
; POOLING-LABEL: add_arg_plus_200000
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32$00030d40
}
define float @load_arg_plus_200000(float* %arg) {
......@@ -50,7 +50,7 @@ entry:
; BLINDINGOM1: lea [[REG:e[a-z]*]],{{[[]}}{{e[a-z]*}}-0x69ea41a7{{[]]}}
; POOLING-LABEL: load_arg_plus_200000
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32$00030d40
}
define i64 @add_arg_plus_64bits(i32 %arg) {
......@@ -70,7 +70,7 @@ entry:
; BLINDINGOM1-NEXT: lea [[RLO]],{{[[]}}[[RLO]]-0x6d3841a8{{[]]}}
; POOLING-LABEL: add_arg_plus_64bits
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32$f46b0400
}
define i64 @load_arg_plus_64bits(i64* %arg) {
......@@ -90,7 +90,7 @@ entry:
; BLINDINGOM1-NEXT: lea e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x708641a9{{[]]}}
; POOLING-LABEL: load_arg_plus_64bits
; POOLING: mov e{{[a-z]x}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
; POOLING: mov e{{[a-z]x}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32$00000004
}
define internal i32 @add_const_8bits(i32 %a) {
......@@ -109,7 +109,7 @@ entry:
; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x73d441aa{{[]]}}
; POOLING-LABEL: add_const_8bits
; POOLING: mov {{[a-z]l}},BYTE PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i8${{[0-9]*}}
; POOLING: mov {{[a-z]l}},BYTE PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i8$0000007b
}
define internal i32 @add_const_16bits(i32 %a) {
......@@ -128,6 +128,6 @@ entry:
; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x772241a7{{[]]}}
; POOLING-LABEL: add_const_16bits
; POOLING: mov {{[a-z]x}},WORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i16${{[0-9]*}}
; POOLING: mov {{[a-z]x}},WORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i16$00007ffe
}
......@@ -38,7 +38,7 @@ define float @undef_float() {
entry:
ret float undef
; CHECK-LABEL: undef_float
; CHECK: fld DWORD PTR {{.*}} .L$float$0
; CHECK: fld DWORD PTR {{.*}} .L$float$00000000
}
define <4 x i1> @undef_v4i1() {
......@@ -191,7 +191,7 @@ entry:
%val = insertelement <4 x float> %arg, float undef, i32 0
ret <4 x float> %val
; CHECK-LABEL: vector_insertelement_arg2
; CHECK: {{movss|insertps}} {{.*}},DWORD PTR {{.*}} .L$float$0
; CHECK: {{movss|insertps}} {{.*}},DWORD PTR {{.*}} .L$float$00000000
}
define float @vector_extractelement_v4f32_index_0() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment