Fix bitcode parser to check type signatures of functions.
Before, type signatures of functions were only checked when called.
This CL fixes this by checking all function signatures.
BUG=None
R=stichnot@chromium.org
Review URL: https://codereview.chromium.org/1579203002 .
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp
index 0907167..e54dd2a 100644
--- a/src/IceConverter.cpp
+++ b/src/IceConverter.cpp
@@ -880,6 +880,8 @@
StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
report_fatal_error(StrBuf.str());
}
+ if (!IceFunc->validateTypeSignature(Ctx))
+ report_fatal_error(IceFunc->getTypeSignatureError(Ctx));
GlobalDeclarationMap[&Func] = IceFunc;
}
// Install global variable declarations.
diff --git a/src/IceGlobalInits.cpp b/src/IceGlobalInits.cpp
index ab53eac..94a38a1 100644
--- a/src/IceGlobalInits.cpp
+++ b/src/IceGlobalInits.cpp
@@ -60,6 +60,56 @@
namespace Ice {
+const Intrinsics::FullIntrinsicInfo *
+FunctionDeclaration::getIntrinsicInfo(const GlobalContext *Ctx,
+ bool *IsIntrinsic) const {
+ *IsIntrinsic = false;
+ if (!hasName())
+ return nullptr;
+ bool BadIntrinsic;
+ const Intrinsics::FullIntrinsicInfo *Info =
+ Ctx->getIntrinsicsInfo().find(getName(), BadIntrinsic);
+ *IsIntrinsic = Info || BadIntrinsic;
+ return Info;
+}
+
+bool FunctionDeclaration::validateRegularTypeSignature() const {
+ for (SizeT i = 0; i < Signature.getNumArgs(); ++i) {
+ if (!isCallParameterType(Signature.getArgType(i)))
+ return false;
+ }
+ return isCallReturnType(Signature.getReturnType());
+}
+
+bool FunctionDeclaration::validateIntrinsicTypeSignature(
+ const Intrinsics::FullIntrinsicInfo *Info) const {
+ if (Signature.getNumArgs() != Info->getNumArgs())
+ return false;
+ for (SizeT i = 0; i < Signature.getNumArgs(); ++i) {
+ if (Signature.getArgType(i) != Info->getArgType(i))
+ return false;
+ }
+ return Signature.getReturnType() == Info->getReturnType();
+}
+
+IceString FunctionDeclaration::getTypeSignatureError(const GlobalContext *Ctx) {
+ std::string Buffer;
+ llvm::raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Invalid";
+ bool IsIntrinsic;
+ const Intrinsics::FullIntrinsicInfo *Info =
+ getIntrinsicInfo(Ctx, &IsIntrinsic);
+ if (IsIntrinsic && Info == nullptr) {
+ StrBuf << " intrinsic name: " << getName();
+ return StrBuf.str();
+ }
+ StrBuf << " type signature for";
+ if (IsIntrinsic)
+ StrBuf << " intrinsic";
+ StrBuf << " " << getName() << ": " << getSignature();
+ return StrBuf.str();
+}
+
void FunctionDeclaration::dumpType(Ostream &Stream) const {
if (!Ice::BuildDefs::dump())
return;
diff --git a/src/IceGlobalInits.h b/src/IceGlobalInits.h
index 28e8142..711a563 100644
--- a/src/IceGlobalInits.h
+++ b/src/IceGlobalInits.h
@@ -21,6 +21,7 @@
#include "IceDefs.h"
#include "IceGlobalContext.h"
+#include "IceIntrinsics.h"
#include "IceTypes.h"
#ifdef __clang__
@@ -156,6 +157,32 @@
return verifyLinkageDefault(Ctx);
}
+ /// Validates that the type signature of the function is correct. Returns true
+ /// if valid.
+ bool validateTypeSignature(const GlobalContext *Ctx) const {
+ bool IsIntrinsic;
+ if (const Intrinsics::FullIntrinsicInfo *Info =
+ getIntrinsicInfo(Ctx, &IsIntrinsic))
+ return validateIntrinsicTypeSignature(Info);
+ return !IsIntrinsic && validateRegularTypeSignature();
+ }
+
+ /// Generates an error message describing why validateTypeSignature returns
+ /// false.
+ IceString getTypeSignatureError(const GlobalContext *Ctx);
+
+ /// Returns corresponding PNaCl intrisic information.
+ const Intrinsics::FullIntrinsicInfo *
+ getIntrinsicInfo(const GlobalContext *Ctx) const {
+ bool BadIntrinsic;
+ return getIntrinsicInfo(Ctx, &BadIntrinsic);
+ }
+
+ /// Same as above, except IsIntrinsic is true if the function is intrinsic
+ /// (even if not a PNaCl intrinsic).
+ const Intrinsics::FullIntrinsicInfo *
+ getIntrinsicInfo(const GlobalContext *Ctx, bool *IsIntrinsic) const;
+
private:
const Ice::FuncSigType Signature;
llvm::CallingConv::ID CallingConv;
@@ -173,12 +200,15 @@
}
bool isIntrinsicName(const GlobalContext *Ctx) const {
- if (!hasName())
- return false;
- bool BadIntrinsic;
- return Ctx->getIntrinsicsInfo().find(getName(), BadIntrinsic) &&
- !BadIntrinsic;
+ bool IsIntrinsic;
+ getIntrinsicInfo(Ctx, &IsIntrinsic);
+ return IsIntrinsic;
}
+
+ bool validateRegularTypeSignature() const;
+
+ bool validateIntrinsicTypeSignature(
+ const Intrinsics::FullIntrinsicInfo *Info) const;
};
/// Models a global variable declaration, and its initializers.
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index a7b367c..13e0870 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -338,6 +338,8 @@
installFunctionNames();
}
+ void verifyFunctionTypeSignatures();
+
void createValueIDs() {
assert(VariableDeclarations);
ValueIDConstants.reserve(VariableDeclarations->size() +
@@ -637,6 +639,14 @@
return Ice::IceType_void;
}
+void TopLevelParser::verifyFunctionTypeSignatures() {
+ const Ice::GlobalContext *Ctx = getTranslator().getContext();
+ for (Ice::FunctionDeclaration *FuncDecl : FunctionDeclarations) {
+ if (!FuncDecl->validateTypeSignature(Ctx))
+ Error(FuncDecl->getTypeSignatureError(Ctx));
+ }
+}
+
// Base class for parsing blocks within the bitcode file. Note: Because this is
// the base class of block parsers, we generate error messages if ParseBlock or
// ParseRecord is not overridden in derived classes.
@@ -2648,16 +2658,7 @@
}
// Check if this direct call is to an Intrinsic (starts with "llvm.")
- bool BadIntrinsic;
- IntrinsicInfo = getTranslator().getContext()->getIntrinsicsInfo().find(
- Fcn->getName(), BadIntrinsic);
- if (BadIntrinsic) {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Invalid PNaCl intrinsic call to " << Fcn->getName();
- Error(StrBuf.str());
- IntrinsicInfo = nullptr;
- }
+ IntrinsicInfo = Fcn->getIntrinsicInfo(getTranslator().getContext());
if (IntrinsicInfo && IntrinsicInfo->getNumArgs() != NumParams) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
@@ -2712,16 +2713,14 @@
if (Signature)
verifyCallArgTypeMatches(Fcn, Index, OpType,
Signature->getArgType(Index));
- if (IntrinsicInfo) {
- verifyCallArgTypeMatches(Fcn, Index, OpType,
- IntrinsicInfo->getArgType(Index));
- } else if (!isCallParameterType(OpType)) {
+ else if (!isCallParameterType(OpType)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Argument " << *Op << " of " << printName(Fcn)
<< " has invalid type: " << Op->getType();
Error(StrBuf.str());
appendErrorInstruction(ReturnType);
+ return;
}
}
@@ -3007,6 +3006,7 @@
if (!GlobalDeclarationNamesAndInitializersInstalled) {
Context->installGlobalNames();
Context->createValueIDs();
+ Context->verifyFunctionTypeSignatures();
std::unique_ptr<Ice::VariableDeclarationList> Globals =
Context->getGlobalVariables();
if (Globals)
diff --git a/tests_lit/llvm2ice_tests/div_legalization.ll b/tests_lit/llvm2ice_tests/div_legalization.ll
index b4832d1..4624dcf 100644
--- a/tests_lit/llvm2ice_tests/div_legalization.ll
+++ b/tests_lit/llvm2ice_tests/div_legalization.ll
@@ -4,9 +4,10 @@
; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 | FileCheck %s
; RUN: %p2i --filetype=obj --disassemble -i %s --args -Om1 | FileCheck %s
-define internal i32 @Sdiv_const8_b(i8 %a) {
+define internal i32 @Sdiv_const8_b(i32 %a32) {
; CHECK-LABEL: Sdiv_const8_b
entry:
+ %a = trunc i32 %a32 to i8
%div = sdiv i8 %a, 12
; CHECK: mov {{.*}},0xc
; CHECK-NOT: idiv 0xc
@@ -14,9 +15,10 @@
ret i32 %div_ext
}
-define internal i32 @Sdiv_const16_b(i16 %a) {
+define internal i32 @Sdiv_const16_b(i32 %a32) {
; CHECK-LABEL: Sdiv_const16_b
entry:
+ %a = trunc i32 %a32 to i16
%div = sdiv i16 %a, 1234
; CHECK: mov {{.*}},0x4d2
; CHECK-NOT: idiv 0x4d2
diff --git a/tests_lit/llvm2ice_tests/rmw.ll b/tests_lit/llvm2ice_tests/rmw.ll
index cd78977..39f5a32 100644
--- a/tests_lit/llvm2ice_tests/rmw.ll
+++ b/tests_lit/llvm2ice_tests/rmw.ll
@@ -40,8 +40,9 @@
; CHECK-LABEL: no_rmw_add_i32_var
; CHECK: add e{{ax|bx|cx|dx|bp|di|si}},DWORD PTR [e{{ax|bx|cx|dx|bp|di|si}}]
-define internal void @rmw_add_i16_var(i32 %addr_arg, i16 %var) {
+define internal void @rmw_add_i16_var(i32 %addr_arg, i32 %var32) {
entry:
+ %var = trunc i32 %var32 to i16
%addr = inttoptr i32 %addr_arg to i16*
%val = load i16, i16* %addr, align 1
%rmw = add i16 %val, %var
@@ -64,8 +65,9 @@
; CHECK-LABEL: rmw_add_i16_imm
; CHECK: add WORD PTR [e{{ax|bx|cx|dx|bp|di|si}}],0x13
-define internal void @rmw_add_i8_var(i32 %addr_arg, i8 %var) {
+define internal void @rmw_add_i8_var(i32 %addr_arg, i32 %var32) {
entry:
+ %var = trunc i32 %var32 to i8
%addr = inttoptr i32 %addr_arg to i8*
%val = load i8, i8* %addr, align 1
%rmw = add i8 %val, %var
diff --git a/tests_lit/parse_errs/Inputs/call-fcn-bad-param-type.tbc b/tests_lit/parse_errs/Inputs/call-fcn-bad-param-type.tbc
new file mode 100644
index 0000000..92b647f
--- /dev/null
+++ b/tests_lit/parse_errs/Inputs/call-fcn-bad-param-type.tbc
@@ -0,0 +1,32 @@
+65535,8,2;
+1,1;
+65535,17,2;
+1,5;
+2;
+7,32;
+7,8;
+21,0,0,1;
+21,0,0;
+65534;
+8,3,0,1,0;
+8,4,0,0,0;
+65535,19,2;
+5,0;
+65534;
+65535,14,2;
+1,1,84,101,115,116;
+1,0,102;
+65534;
+65535,12,2;
+1,1;
+65535,11,2;
+1,1;
+4,2;
+1,2;
+4,2;
+65534;
+2,1,1,0;
+34,0,5,2;
+10;
+65534;
+65534;
diff --git a/tests_lit/parse_errs/bad-intrinsic-arg.test b/tests_lit/parse_errs/bad-intrinsic-arg.test
index 5e3c6e9..ffbb894 100644
--- a/tests_lit/parse_errs/bad-intrinsic-arg.test
+++ b/tests_lit/parse_errs/bad-intrinsic-arg.test
@@ -8,7 +8,7 @@
; RUN: -allow-externally-defined-symbols 2>&1 \
; RUN: | FileCheck %s
-; CHECK: Argument 1 of llvm.nacl.setjmp expects i32. Found: double
+; CHECK: Invalid type signature for intrinsic llvm.nacl.setjmp: i32 (double)
; RUN: pnacl-bcfuzz -bitcode-as-text \
; RUN: %p/Inputs/bad-intrinsic-arg.tbc -output - \
diff --git a/tests_lit/parse_errs/call-fcn-bad-param-type.ll b/tests_lit/parse_errs/call-fcn-bad-param-type.ll
index b7246e0..093807f 100644
--- a/tests_lit/parse_errs/call-fcn-bad-param-type.ll
+++ b/tests_lit/parse_errs/call-fcn-bad-param-type.ll
@@ -1,5 +1,5 @@
-; Test that even if a call parameter matches its declaration, it must still
-; be a legal call parameter type (unless declaration is intrinsic).
+; Test that a function parameter must be a legal parameter type (unless
+; declaration is intrinsic).
; REQUIRES: no_minimal_build
@@ -7,10 +7,10 @@
; RUN: -allow-externally-defined-symbols | FileCheck %s
declare void @f(i8);
+; CHECK: Invalid type signature for f: void (i8)
define void @Test() {
entry:
call void @f(i8 1)
-; CHECK: Argument 1 of f has invalid type: i8
ret void
}
diff --git a/tests_lit/parse_errs/call-fcn-bad-param-type.test b/tests_lit/parse_errs/call-fcn-bad-param-type.test
new file mode 100644
index 0000000..d4df2fc
--- /dev/null
+++ b/tests_lit/parse_errs/call-fcn-bad-param-type.test
@@ -0,0 +1,53 @@
+; Show that we check parameter types of a function call against paramter types
+; of called function.
+
+; REQUIRES: no_minimal_build
+
+; RUN: not %pnacl_sz -bitcode-as-text %p/Inputs/call-fcn-bad-param-type.tbc \
+; RUN: -bitcode-format=pnacl -notranslate -build-on-read \
+; RUN: -allow-externally-defined-symbols 2>&1 \
+; RUN: | FileCheck %s
+
+; RUN: pnacl-bcfuzz -bitcode-as-text -output - \
+; RUN: %p/Inputs/call-fcn-bad-param-type.tbc \
+; RUN: | not pnacl-bcdis -no-records | FileCheck %s --check-prefix=DIS
+
+; DIS: module { // BlockID = 8
+; DIS-NEXT: version 1;
+; DIS-NEXT: types { // BlockID = 17
+; DIS-NEXT: count 5;
+; DIS-NEXT: @t0 = void;
+; DIS-NEXT: @t1 = i32;
+; DIS-NEXT: @t2 = i8;
+; DIS-NEXT: @t3 = void (i32);
+; DIS-NEXT: @t4 = void ();
+; DIS-NEXT: }
+; DIS-NEXT: declare external void @f0(i32);
+; DIS-NEXT: define external void @f1();
+; DIS-NEXT: globals { // BlockID = 19
+; DIS-NEXT: count 0;
+; DIS-NEXT: }
+; DIS-NEXT: valuesymtab { // BlockID = 14
+; DIS-NEXT: @f1 : "Test";
+; DIS-NEXT: @f0 : "f";
+; DIS-NEXT: }
+; DIS-NEXT: function void @f1() { // BlockID = 12
+; DIS-NEXT: blocks 1;
+; DIS-NEXT: constants { // BlockID = 11
+; DIS-NEXT: i32:
+; DIS-NEXT: %c0 = i32 1;
+; DIS-NEXT: i8:
+; DIS-NEXT: %c1 = i8 1;
+; DIS-NEXT: }
+; DIS-NEXT: %b0:
+; DIS-NEXT: %v0 = add i8 %c1, %c1;
+; DIS-NEXT: call void @f0(i8 %c1);
+; DIS-NEXT: Error({{.*}}): Parameter 1 mismatch: i8 and i32
+; CHECK: Argument 1 of f expects i32. Found: i8
+; DIS-NEXT: ret void;
+; DIS-NEXT: }
+; DIS-NEXT: }
+
+
+
+
diff --git a/tests_lit/parse_errs/call-fcn-bad-return-type.ll b/tests_lit/parse_errs/call-fcn-bad-return-type.ll
index 873e05c..73a7c16 100644
--- a/tests_lit/parse_errs/call-fcn-bad-return-type.ll
+++ b/tests_lit/parse_errs/call-fcn-bad-return-type.ll
@@ -6,12 +6,15 @@
; RUN: %p2i --expect-fail -i %s --insts --args \
; RUN: -allow-externally-defined-symbols | FileCheck %s
-declare i1 @f();
+declare i32 @f();
-define void @Test() {
+declare i64 @g();
+
+define void @Test(i32 %ifcn) {
entry:
- %v = call i1 @f()
-; CHECK: Return type of f is invalid: i1
+ %fcn = inttoptr i32 %ifcn to i1()*
+ %v = call i1 %fcn()
+; CHECK: Return type of function is invalid: i1
ret void
}
diff --git a/tests_lit/parse_errs/fcn-bad-param-type.ll b/tests_lit/parse_errs/fcn-bad-param-type.ll
new file mode 100644
index 0000000..a4faab2
--- /dev/null
+++ b/tests_lit/parse_errs/fcn-bad-param-type.ll
@@ -0,0 +1,16 @@
+; Test that even if a call parameter matches its declaration, it must still
+; be a legal call parameter type (unless declaration is intrinsic).
+
+; REQUIRES: no_minimal_build
+
+; RUN: %p2i --expect-fail -i %s --insts --args \
+; RUN: -allow-externally-defined-symbols | FileCheck %s
+
+declare void @f(i8);
+; CHECK: Invalid type signature for f: void (i8)
+
+define void @Test() {
+entry:
+ call void @f(i8 1)
+ ret void
+}
diff --git a/tests_lit/parse_errs/nacl-fake-intrinsic.ll b/tests_lit/parse_errs/nacl-fake-intrinsic.ll
index cef88d7..f1e066c 100644
--- a/tests_lit/parse_errs/nacl-fake-intrinsic.ll
+++ b/tests_lit/parse_errs/nacl-fake-intrinsic.ll
@@ -1,34 +1,11 @@
; Tests that we don't get fooled by a fake NaCl intrinsic.
-; TODO(kschimpf) Find way to run this through p2i. Note: Can't do this
-; currently because run-pnacl-sz.py raises exception on error,
-; and output is lost.
-; RUN: %if --need=allow_dump --command llvm-as < %s \
-; RUN: | %if --need=allow_dump --command pnacl-freeze \
-; RUN -allow-local-symbol-tables \
-; RUN: | %if --need=allow_dump --command not %pnacl_sz -notranslate \
-; RUN: -verbose=inst -build-on-read \
-; RUN: -allow-pnacl-reader-error-recovery \
-; RUN: -allow-local-symbol-tables \
-; RUN: -filetype=obj -o /dev/null \
-; RUN: | %if --need=allow_dump --command FileCheck %s
+; REQUIRES: allow_dump
-; RUN: %if --need=no_dump --command llvm-as < %s \
-; RUN: | %if --need=no_dump --command pnacl-freeze \
-; RUN -allow-local-symbol-tables \
-; RUN: | %if --need=no_dump --command not %pnacl_sz -notranslate \
-; RUN: -verbose=inst -build-on-read \
-; RUN: -allow-pnacl-reader-error-recovery \
-; RUN: -allow-local-symbol-tables \
-; RUN: -filetype=obj -o /dev/null \
-; RUN: | %if --need=no_dump --command FileCheck %s --check-prefix=MIN
+; RUN: %p2i --expect-fail -i %s --insts --args \
+; RUN: -verbose=inst -allow-externally-defined-symbols \
+; RUN: | FileCheck %s
declare i32 @llvm.fake.i32(i32)
-define i32 @testFake(i32 %v) {
- %r = call i32 @llvm.fake.i32(i32 %v)
- ret i32 %r
-}
-
-; CHECK: Error({{.*}}): Invalid PNaCl intrinsic call to llvm.fake.i32
-; MIN: Error({{.*}}): Invalid function record: <34 0 3 1>
+; CHECK: Error({{.*}}): Invalid intrinsic name: llvm.fake.i32
diff --git a/tests_lit/reader_tests/compare.ll b/tests_lit/reader_tests/compare.ll
index 7acc3b0..bb2229b 100644
--- a/tests_lit/reader_tests/compare.ll
+++ b/tests_lit/reader_tests/compare.ll
@@ -4,7 +4,7 @@
; RUN: %p2i -i %s --args -notranslate -timing | \
; RUN: FileCheck --check-prefix=NOIR %s
-define internal i1 @IcmpI1(i32 %p1, i32 %p2) {
+define internal void @IcmpI1(i32 %p1, i32 %p2) {
entry:
%a1 = trunc i32 %p1 to i1
%a2 = trunc i32 %p2 to i1
@@ -18,10 +18,10 @@
%vsge = icmp sge i1 %a1, %a2
%vslt = icmp slt i1 %a1, %a2
%vsle = icmp sle i1 %a1, %a2
- ret i1 %veq
+ ret void
}
-; CHECK: define internal i1 @IcmpI1(i32 %p1, i32 %p2) {
+; CHECK: define internal void @IcmpI1(i32 %p1, i32 %p2) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %a1 = trunc i32 %p1 to i1
; CHECK-NEXT: %a2 = trunc i32 %p2 to i1
@@ -35,10 +35,10 @@
; CHECK-NEXT: %vsge = icmp sge i1 %a1, %a2
; CHECK-NEXT: %vslt = icmp slt i1 %a1, %a2
; CHECK-NEXT: %vsle = icmp sle i1 %a1, %a2
-; CHECK-NEXT: ret i1 %veq
+; CHECK-NEXT: ret void
; CHECK-NEXT: }
-define internal i1 @IcmpI8(i32 %p1, i32 %p2) {
+define internal void @IcmpI8(i32 %p1, i32 %p2) {
entry:
%a1 = trunc i32 %p1 to i8
%a2 = trunc i32 %p2 to i8
@@ -52,10 +52,10 @@
%vsge = icmp sge i8 %a1, %a2
%vslt = icmp slt i8 %a1, %a2
%vsle = icmp sle i8 %a1, %a2
- ret i1 %veq
+ ret void
}
-; CHECK-NEXT: define internal i1 @IcmpI8(i32 %p1, i32 %p2) {
+; CHECK-NEXT: define internal void @IcmpI8(i32 %p1, i32 %p2) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %a1 = trunc i32 %p1 to i8
; CHECK-NEXT: %a2 = trunc i32 %p2 to i8
@@ -69,10 +69,10 @@
; CHECK-NEXT: %vsge = icmp sge i8 %a1, %a2
; CHECK-NEXT: %vslt = icmp slt i8 %a1, %a2
; CHECK-NEXT: %vsle = icmp sle i8 %a1, %a2
-; CHECK-NEXT: ret i1 %veq
+; CHECK-NEXT: ret void
; CHECK-NEXT: }
-define internal i1 @IcmpI16(i32 %p1, i32 %p2) {
+define internal void @IcmpI16(i32 %p1, i32 %p2) {
entry:
%a1 = trunc i32 %p1 to i16
%a2 = trunc i32 %p2 to i16
@@ -86,10 +86,10 @@
%vsge = icmp sge i16 %a1, %a2
%vslt = icmp slt i16 %a1, %a2
%vsle = icmp sle i16 %a1, %a2
- ret i1 %veq
+ ret void
}
-; CHECK-NEXT: define internal i1 @IcmpI16(i32 %p1, i32 %p2) {
+; CHECK-NEXT: define internal void @IcmpI16(i32 %p1, i32 %p2) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %a1 = trunc i32 %p1 to i16
; CHECK-NEXT: %a2 = trunc i32 %p2 to i16
@@ -103,10 +103,10 @@
; CHECK-NEXT: %vsge = icmp sge i16 %a1, %a2
; CHECK-NEXT: %vslt = icmp slt i16 %a1, %a2
; CHECK-NEXT: %vsle = icmp sle i16 %a1, %a2
-; CHECK-NEXT: ret i1 %veq
+; CHECK-NEXT: ret void
; CHECK-NEXT: }
-define internal i1 @IcmpI32(i32 %a1, i32 %a2) {
+define internal void @IcmpI32(i32 %a1, i32 %a2) {
entry:
%veq = icmp eq i32 %a1, %a2
%vne = icmp ne i32 %a1, %a2
@@ -118,10 +118,10 @@
%vsge = icmp sge i32 %a1, %a2
%vslt = icmp slt i32 %a1, %a2
%vsle = icmp sle i32 %a1, %a2
- ret i1 %veq
+ ret void
}
-; CHECK-NEXT: define internal i1 @IcmpI32(i32 %a1, i32 %a2) {
+; CHECK-NEXT: define internal void @IcmpI32(i32 %a1, i32 %a2) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %veq = icmp eq i32 %a1, %a2
; CHECK-NEXT: %vne = icmp ne i32 %a1, %a2
@@ -133,10 +133,10 @@
; CHECK-NEXT: %vsge = icmp sge i32 %a1, %a2
; CHECK-NEXT: %vslt = icmp slt i32 %a1, %a2
; CHECK-NEXT: %vsle = icmp sle i32 %a1, %a2
-; CHECK-NEXT: ret i1 %veq
+; CHECK-NEXT: ret void
; CHECK-NEXT: }
-define internal i1 @IcmpI64(i64 %a1, i64 %a2) {
+define internal void @IcmpI64(i64 %a1, i64 %a2) {
entry:
%veq = icmp eq i64 %a1, %a2
%vne = icmp ne i64 %a1, %a2
@@ -148,10 +148,10 @@
%vsge = icmp sge i64 %a1, %a2
%vslt = icmp slt i64 %a1, %a2
%vsle = icmp sle i64 %a1, %a2
- ret i1 %veq
+ ret void
}
-; CHECK-NEXT: define internal i1 @IcmpI64(i64 %a1, i64 %a2) {
+; CHECK-NEXT: define internal void @IcmpI64(i64 %a1, i64 %a2) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %veq = icmp eq i64 %a1, %a2
; CHECK-NEXT: %vne = icmp ne i64 %a1, %a2
@@ -163,7 +163,7 @@
; CHECK-NEXT: %vsge = icmp sge i64 %a1, %a2
; CHECK-NEXT: %vslt = icmp slt i64 %a1, %a2
; CHECK-NEXT: %vsle = icmp sle i64 %a1, %a2
-; CHECK-NEXT: ret i1 %veq
+; CHECK-NEXT: ret void
; CHECK-NEXT: }
define internal <4 x i1> @IcmpV4xI1(<4 x i1> %a1, <4 x i1> %a2) {
@@ -346,7 +346,7 @@
; CHECK-NEXT: ret <4 x i1> %veq
; CHECK-NEXT: }
-define internal i1 @FcmpFloat(float %a1, float %a2) {
+define internal void @FcmpFloat(float %a1, float %a2) {
entry:
%vfalse = fcmp false float %a1, %a2
%voeq = fcmp oeq float %a1, %a2
@@ -364,10 +364,10 @@
%vune = fcmp une float %a1, %a2
%vuno = fcmp uno float %a1, %a2
%vtrue = fcmp true float %a1, %a2
- ret i1 %voeq
+ ret void
}
-; CHECK-NEXT: define internal i1 @FcmpFloat(float %a1, float %a2) {
+; CHECK-NEXT: define internal void @FcmpFloat(float %a1, float %a2) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %vfalse = fcmp false float %a1, %a2
; CHECK-NEXT: %voeq = fcmp oeq float %a1, %a2
@@ -385,10 +385,10 @@
; CHECK-NEXT: %vune = fcmp une float %a1, %a2
; CHECK-NEXT: %vuno = fcmp uno float %a1, %a2
; CHECK-NEXT: %vtrue = fcmp true float %a1, %a2
-; CHECK-NEXT: ret i1 %voeq
+; CHECK-NEXT: ret void
; CHECK-NEXT: }
-define internal i1 @FcmpDouble(double %a1, double %a2) {
+define internal void @FcmpDouble(double %a1, double %a2) {
entry:
%vfalse = fcmp false double %a1, %a2
%voeq = fcmp oeq double %a1, %a2
@@ -406,10 +406,10 @@
%vune = fcmp une double %a1, %a2
%vuno = fcmp uno double %a1, %a2
%vtrue = fcmp true double %a1, %a2
- ret i1 %voeq
+ ret void
}
-; CHECK-NEXT: define internal i1 @FcmpDouble(double %a1, double %a2) {
+; CHECK-NEXT: define internal void @FcmpDouble(double %a1, double %a2) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %vfalse = fcmp false double %a1, %a2
; CHECK-NEXT: %voeq = fcmp oeq double %a1, %a2
@@ -427,7 +427,7 @@
; CHECK-NEXT: %vune = fcmp une double %a1, %a2
; CHECK-NEXT: %vuno = fcmp uno double %a1, %a2
; CHECK-NEXT: %vtrue = fcmp true double %a1, %a2
-; CHECK-NEXT: ret i1 %voeq
+; CHECK-NEXT: ret void
; CHECK-NEXT: }
define internal <4 x i1> @FcmpV4xFloat(<4 x float> %a1, <4 x float> %a2) {