libbcc
Change-Id: Ieaa3ebd5a38f370752495549f8870b534eeedfc5
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index b02cc3e..5719960 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -236,6 +236,13 @@
EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble, "002.05000e12").convertToDouble());
EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble, "002.05000e+12").convertToDouble());
EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble, "002.05000e-12").convertToDouble());
+
+ // These are "carefully selected" to overflow the fast log-base
+ // calculations in APFloat.cpp
+ EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "99e99999").isInfinity());
+ EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-99e99999").isInfinity());
+ EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "1e-99999").isPosZero());
+ EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-1e-99999").isNegZero());
}
TEST(APFloatTest, fromHexadecimalString) {
@@ -337,6 +344,35 @@
ASSERT_EQ("8.731834E+2", convertToString(873.1834, 0, 0));
}
+static APInt nanbits(const fltSemantics &Sem,
+ bool SNaN, bool Negative, uint64_t fill) {
+ APInt apfill(64, fill);
+ if (SNaN)
+ return APFloat::getSNaN(Sem, Negative, &apfill).bitcastToAPInt();
+ else
+ return APFloat::getQNaN(Sem, Negative, &apfill).bitcastToAPInt();
+}
+
+TEST(APFloatTest, makeNaN) {
+ ASSERT_EQ(0x7fc00000, nanbits(APFloat::IEEEsingle, false, false, 0));
+ ASSERT_EQ(0xffc00000, nanbits(APFloat::IEEEsingle, false, true, 0));
+ ASSERT_EQ(0x7fc0ae72, nanbits(APFloat::IEEEsingle, false, false, 0xae72));
+ ASSERT_EQ(0x7fffae72, nanbits(APFloat::IEEEsingle, false, false, 0xffffae72));
+ ASSERT_EQ(0x7fa00000, nanbits(APFloat::IEEEsingle, true, false, 0));
+ ASSERT_EQ(0xffa00000, nanbits(APFloat::IEEEsingle, true, true, 0));
+ ASSERT_EQ(0x7f80ae72, nanbits(APFloat::IEEEsingle, true, false, 0xae72));
+ ASSERT_EQ(0x7fbfae72, nanbits(APFloat::IEEEsingle, true, false, 0xffffae72));
+
+ ASSERT_EQ(0x7ff8000000000000ULL, nanbits(APFloat::IEEEdouble, false, false, 0));
+ ASSERT_EQ(0xfff8000000000000ULL, nanbits(APFloat::IEEEdouble, false, true, 0));
+ ASSERT_EQ(0x7ff800000000ae72ULL, nanbits(APFloat::IEEEdouble, false, false, 0xae72));
+ ASSERT_EQ(0x7fffffffffffae72ULL, nanbits(APFloat::IEEEdouble, false, false, 0xffffffffffffae72ULL));
+ ASSERT_EQ(0x7ff4000000000000ULL, nanbits(APFloat::IEEEdouble, true, false, 0));
+ ASSERT_EQ(0xfff4000000000000ULL, nanbits(APFloat::IEEEdouble, true, true, 0));
+ ASSERT_EQ(0x7ff000000000ae72ULL, nanbits(APFloat::IEEEdouble, true, false, 0xae72));
+ ASSERT_EQ(0x7ff7ffffffffae72ULL, nanbits(APFloat::IEEEdouble, true, false, 0xffffffffffffae72ULL));
+}
+
#ifdef GTEST_HAS_DEATH_TEST
TEST(APFloatTest, SemanticsDeath) {
EXPECT_DEATH(APFloat(APFloat::IEEEsingle, 0.0f).convertToDouble(), "Float semantics are not IEEEdouble");
diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp
index 3dcdc39..413f068 100644
--- a/unittests/ADT/StringMapTest.cpp
+++ b/unittests/ADT/StringMapTest.cpp
@@ -191,6 +191,7 @@
testKeyFirst, testKeyFirst + testKeyLength, 1u);
EXPECT_STREQ(testKey, entry->first());
EXPECT_EQ(1u, entry->second);
+ free(entry);
}
// Test insert() method.
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index 84ee0e3..b85f724 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -65,6 +65,8 @@
stubsAllocated = 0;
}
+ void setSizeRequired(bool Required) { SizeRequired = Required; }
+
virtual void setMemoryWritable() { Base->setMemoryWritable(); }
virtual void setMemoryExecutable() { Base->setMemoryExecutable(); }
virtual void setPoisonMemory(bool poison) { Base->setPoisonMemory(poison); }
@@ -628,6 +630,54 @@
<< " not 7 from the IR version.";
}
+TEST_F(JITTest, NeedsExactSizeWithManyGlobals) {
+ // PR5291: When the JMM needed the exact size of function bodies before
+ // starting to emit them, the JITEmitter would modify a set while iterating
+ // over it.
+ TheJIT->DisableLazyCompilation(true);
+ RJMM->setSizeRequired(true);
+
+ LoadAssembly("@A = global i32 42 "
+ "@B = global i32* @A "
+ "@C = global i32** @B "
+ "@D = global i32*** @C "
+ "@E = global i32**** @D "
+ "@F = global i32***** @E "
+ "@G = global i32****** @F "
+ "@H = global i32******* @G "
+ "@I = global i32******** @H "
+ "define i32********* @test() { "
+ " ret i32********* @I "
+ "}");
+ Function *testIR = M->getFunction("test");
+ int32_t********* (*test)() = reinterpret_cast<int32_t*********(*)()>(
+ (intptr_t)TheJIT->getPointerToFunction(testIR));
+ EXPECT_EQ(42, *********test());
+}
+
+TEST_F(JITTest, EscapedLazyStubStillCallable) {
+ TheJIT->DisableLazyCompilation(false);
+ LoadAssembly("define internal i32 @stubbed() { "
+ " ret i32 42 "
+ "} "
+ " "
+ "define i32()* @get_stub() { "
+ " ret i32()* @stubbed "
+ "} ");
+ typedef int32_t(*StubTy)();
+
+ // Call get_stub() to get the address of @stubbed without actually JITting it.
+ Function *get_stubIR = M->getFunction("get_stub");
+ StubTy (*get_stub)() = reinterpret_cast<StubTy(*)()>(
+ (intptr_t)TheJIT->getPointerToFunction(get_stubIR));
+ StubTy stubbed = get_stub();
+ // Now get_stubIR is the only reference to stubbed's stub.
+ get_stubIR->eraseFromParent();
+ // Now there are no references inside the JIT, but we've got a pointer outside
+ // it. The stub should be callable and return the right value.
+ EXPECT_EQ(42, stubbed());
+}
+
// Converts the LLVM assembly to bitcode and returns it in a std::string. An
// empty string indicates an error.
std::string AssembleToBitcode(LLVMContext &Context, const char *Assembly) {
diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
new file mode 100644
index 0000000..8997d39
--- /dev/null
+++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
@@ -0,0 +1,164 @@
+//===- MultiJITTest.cpp - Unit tests for instantiating multiple JITs ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Assembly/Parser.h"
+#include "llvm/ExecutionEngine/GenericValue.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/Support/SourceMgr.h"
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+
+bool LoadAssemblyInto(Module *M, const char *assembly) {
+ SMDiagnostic Error;
+ bool success =
+ NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ Error.Print("", os);
+ EXPECT_TRUE(success) << os.str();
+ return success;
+}
+
+void createModule1(LLVMContext &Context1, Module *&M1, Function *&FooF1) {
+ M1 = new Module("test1", Context1);
+ LoadAssemblyInto(M1,
+ "define i32 @add1(i32 %ArgX1) { "
+ "entry: "
+ " %addresult = add i32 1, %ArgX1 "
+ " ret i32 %addresult "
+ "} "
+ " "
+ "define i32 @foo1() { "
+ "entry: "
+ " %add1 = call i32 @add1(i32 10) "
+ " ret i32 %add1 "
+ "} ");
+ FooF1 = M1->getFunction("foo1");
+}
+
+void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) {
+ M2 = new Module("test2", Context2);
+ LoadAssemblyInto(M2,
+ "define i32 @add2(i32 %ArgX2) { "
+ "entry: "
+ " %addresult = add i32 2, %ArgX2 "
+ " ret i32 %addresult "
+ "} "
+ " "
+ "define i32 @foo2() { "
+ "entry: "
+ " %add2 = call i32 @add2(i32 10) "
+ " ret i32 %add2 "
+ "} ");
+ FooF2 = M2->getFunction("foo2");
+}
+
+TEST(MultiJitTest, EagerMode) {
+ LLVMContext Context1;
+ Module *M1 = 0;
+ Function *FooF1 = 0;
+ createModule1(Context1, M1, FooF1);
+
+ LLVMContext Context2;
+ Module *M2 = 0;
+ Function *FooF2 = 0;
+ createModule2(Context2, M2, FooF2);
+
+ // Now we create the JIT in eager mode
+ OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ EE1->DisableLazyCompilation(true);
+ OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ EE2->DisableLazyCompilation(true);
+
+ // Call the `foo' function with no arguments:
+ std::vector<GenericValue> noargs;
+ GenericValue gv1 = EE1->runFunction(FooF1, noargs);
+ GenericValue gv2 = EE2->runFunction(FooF2, noargs);
+
+ // Import result of execution:
+ EXPECT_EQ(gv1.IntVal, 11);
+ EXPECT_EQ(gv2.IntVal, 12);
+
+ EE1->freeMachineCodeForFunction(FooF1);
+ EE2->freeMachineCodeForFunction(FooF2);
+}
+
+TEST(MultiJitTest, LazyMode) {
+ LLVMContext Context1;
+ Module *M1 = 0;
+ Function *FooF1 = 0;
+ createModule1(Context1, M1, FooF1);
+
+ LLVMContext Context2;
+ Module *M2 = 0;
+ Function *FooF2 = 0;
+ createModule2(Context2, M2, FooF2);
+
+ // Now we create the JIT in lazy mode
+ OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ EE1->DisableLazyCompilation(false);
+ OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ EE2->DisableLazyCompilation(false);
+
+ // Call the `foo' function with no arguments:
+ std::vector<GenericValue> noargs;
+ GenericValue gv1 = EE1->runFunction(FooF1, noargs);
+ GenericValue gv2 = EE2->runFunction(FooF2, noargs);
+
+ // Import result of execution:
+ EXPECT_EQ(gv1.IntVal, 11);
+ EXPECT_EQ(gv2.IntVal, 12);
+
+ EE1->freeMachineCodeForFunction(FooF1);
+ EE2->freeMachineCodeForFunction(FooF2);
+}
+
+extern "C" {
+ extern void *getPointerToNamedFunction(const char *Name);
+}
+
+TEST(MultiJitTest, JitPool) {
+ LLVMContext Context1;
+ Module *M1 = 0;
+ Function *FooF1 = 0;
+ createModule1(Context1, M1, FooF1);
+
+ LLVMContext Context2;
+ Module *M2 = 0;
+ Function *FooF2 = 0;
+ createModule2(Context2, M2, FooF2);
+
+ // Now we create two JITs
+ OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+
+ Function *F1 = EE1->FindFunctionNamed("foo1");
+ void *foo1 = EE1->getPointerToFunction(F1);
+
+ Function *F2 = EE2->FindFunctionNamed("foo2");
+ void *foo2 = EE2->getPointerToFunction(F2);
+
+ // Function in M1
+ EXPECT_EQ(getPointerToNamedFunction("foo1"), foo1);
+
+ // Function in M2
+ EXPECT_EQ(getPointerToNamedFunction("foo2"), foo2);
+
+ // Symbol search
+ EXPECT_EQ((intptr_t)getPointerToNamedFunction("getPointerToNamedFunction"),
+ (intptr_t)&getPointerToNamedFunction);
+}
+
+} // anonymous namespace
diff --git a/unittests/Makefile.unittest b/unittests/Makefile.unittest
index 6fbef54..b1c1d2c 100644
--- a/unittests/Makefile.unittest
+++ b/unittests/Makefile.unittest
@@ -28,6 +28,15 @@
CPP.Flags += $(NO_VARIADIC_MACROS)
TESTLIBS = -lGoogleTest -lUnitTestMain
+ifeq ($(ENABLE_SHARED), 1)
+ # Add the absolute path to the dynamic library. This is ok because
+ # we'll never install unittests.
+ LD.Flags += $(RPATH) -Wl,$(LibDir)
+ # Also set {DYLD,LD}_LIBRARY_PATH because OSX ignores the rpath most
+ # of the time.
+ Run.Shared := $(SHLIBPATH_VAR)="$(LibDir)$${$(SHLIBPATH_VAR):+:}$$$(SHLIBPATH_VAR)"
+endif
+
$(LLVMUnitTestExe): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths)
$(Echo) Linking $(BuildMode) unit test $(TESTNAME) $(StripWarnMsg)
$(Verb) $(Link) -o $@ $(TOOLLINKOPTS) $(ObjectsO) $(ProjLibsOptions) \
@@ -38,6 +47,6 @@
all:: $(LLVMUnitTestExe)
unitcheck:: $(LLVMUnitTestExe)
- $(LLVMUnitTestExe)
+ $(Run.Shared) $(LLVMUnitTestExe)
endif
diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp
index 2a01f3a..6c0fca9 100644
--- a/unittests/Support/AllocatorTest.cpp
+++ b/unittests/Support/AllocatorTest.cpp
@@ -88,7 +88,7 @@
Alloc.Allocate(4096 - sizeof(MemSlab), 0);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
- // If we dont't allocate a new slab, then we will have overflowed.
+ // If we don't allocate a new slab, then we will have overflowed.
Alloc.Allocate(1, 0);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
diff --git a/unittests/Support/RegexTest.cpp b/unittests/Support/RegexTest.cpp
index 44c7e55..65b66c3 100644
--- a/unittests/Support/RegexTest.cpp
+++ b/unittests/Support/RegexTest.cpp
@@ -62,4 +62,33 @@
EXPECT_TRUE(r5.match(String));
}
+TEST_F(RegexTest, Substitution) {
+ std::string Error;
+
+ EXPECT_EQ("aNUMber", Regex("[0-9]+").sub("NUM", "a1234ber"));
+
+ // Standard Escapes
+ EXPECT_EQ("a\\ber", Regex("[0-9]+").sub("\\\\", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+ EXPECT_EQ("a\nber", Regex("[0-9]+").sub("\\n", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+ EXPECT_EQ("a\tber", Regex("[0-9]+").sub("\\t", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+ EXPECT_EQ("ajber", Regex("[0-9]+").sub("\\j", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+
+ EXPECT_EQ("aber", Regex("[0-9]+").sub("\\", "a1234ber", &Error));
+ EXPECT_EQ(Error, "replacement string contained trailing backslash");
+
+ // Backreferences
+ EXPECT_EQ("aa1234bber", Regex("a[0-9]+b").sub("a\\0b", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+
+ EXPECT_EQ("a1234ber", Regex("a([0-9]+)b").sub("a\\1b", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+
+ EXPECT_EQ("aber", Regex("a[0-9]+b").sub("a\\100b", "a1234ber", &Error));
+ EXPECT_EQ(Error, "invalid backreference string '100'");
+}
+
}
diff --git a/unittests/VMCore/DerivedTypesTest.cpp b/unittests/VMCore/DerivedTypesTest.cpp
index 11b4dff..2e0450d 100644
--- a/unittests/VMCore/DerivedTypesTest.cpp
+++ b/unittests/VMCore/DerivedTypesTest.cpp
@@ -18,14 +18,16 @@
TEST(OpaqueTypeTest, RegisterWithContext) {
LLVMContext C;
- LLVMContextImpl *pImpl = C.pImpl;
+ LLVMContextImpl *pImpl = C.pImpl;
- EXPECT_EQ(0u, pImpl->OpaqueTypes.size());
+ // 1 refers to the AlwaysOpaqueTy allocated in the Context's constructor and
+ // destroyed in the destructor.
+ EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
{
PATypeHolder Type = OpaqueType::get(C);
- EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
+ EXPECT_EQ(2u, pImpl->OpaqueTypes.size());
}
- EXPECT_EQ(0u, pImpl->OpaqueTypes.size());
+ EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
}
} // namespace
diff --git a/unittests/VMCore/MetadataTest.cpp b/unittests/VMCore/MetadataTest.cpp
index e374789..13bf27e 100644
--- a/unittests/VMCore/MetadataTest.cpp
+++ b/unittests/VMCore/MetadataTest.cpp
@@ -20,11 +20,15 @@
namespace {
-LLVMContext &Context = getGlobalContext();
+class MetadataTest : public testing::Test {
+protected:
+ LLVMContext Context;
+};
+typedef MetadataTest MDStringTest;
// Test that construction of MDString with different value produces different
// MDString objects, even with the same string pointer and nulls in the string.
-TEST(MDStringTest, CreateDifferent) {
+TEST_F(MDStringTest, CreateDifferent) {
char x[3] = { 'f', 0, 'A' };
MDString *s1 = MDString::get(Context, StringRef(&x[0], 3));
x[2] = 'B';
@@ -34,7 +38,7 @@
// Test that creation of MDStrings with the same string contents produces the
// same MDString object, even with different pointers.
-TEST(MDStringTest, CreateSame) {
+TEST_F(MDStringTest, CreateSame) {
char x[4] = { 'a', 'b', 'c', 'X' };
char y[4] = { 'a', 'b', 'c', 'Y' };
@@ -44,7 +48,7 @@
}
// Test that MDString prints out the string we fed it.
-TEST(MDStringTest, PrintingSimple) {
+TEST_F(MDStringTest, PrintingSimple) {
char *str = new char[13];
strncpy(str, "testing 1 2 3", 13);
MDString *s = MDString::get(Context, StringRef(str, 13));
@@ -58,7 +62,7 @@
}
// Test printing of MDString with non-printable characters.
-TEST(MDStringTest, PrintingComplex) {
+TEST_F(MDStringTest, PrintingComplex) {
char str[5] = {0, '\n', '"', '\\', -1};
MDString *s = MDString::get(Context, StringRef(str+0, 5));
std::string Str;
@@ -67,8 +71,10 @@
EXPECT_STREQ("metadata !\"\\00\\0A\\22\\5C\\FF\"", oss.str().c_str());
}
+typedef MetadataTest MDNodeTest;
+
// Test the two constructors, and containing other Constants.
-TEST(MDNodeTest, Simple) {
+TEST_F(MDNodeTest, Simple) {
char x[3] = { 'a', 'b', 'c' };
char y[3] = { '1', '2', '3' };
@@ -101,7 +107,7 @@
EXPECT_EQ(n1, n2->getOperand(0));
}
-TEST(MDNodeTest, Delete) {
+TEST_F(MDNodeTest, Delete) {
Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1);
Instruction *I = new BitCastInst(C, Type::getInt32Ty(getGlobalContext()));
@@ -115,8 +121,9 @@
}
TEST(NamedMDNodeTest, Search) {
- Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1);
- Constant *C2 = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 2);
+ LLVMContext Context;
+ Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1);
+ Constant *C2 = ConstantInt::get(Type::getInt32Ty(Context), 2);
Value *const V = C;
Value *const V2 = C2;
@@ -125,9 +132,9 @@
MDNode *Nodes[2] = { n, n2 };
- Module *M = new Module("MyModule", getGlobalContext());
+ Module *M = new Module("MyModule", Context);
const char *Name = "llvm.NMD1";
- NamedMDNode *NMD = NamedMDNode::Create(getGlobalContext(), Name, &Nodes[0], 2, M);
+ NamedMDNode *NMD = NamedMDNode::Create(Context, Name, &Nodes[0], 2, M);
std::string Str;
raw_string_ostream oss(Str);
NMD->print(oss);
diff --git a/unittests/VMCore/VerifierTest.cpp b/unittests/VMCore/VerifierTest.cpp
new file mode 100644
index 0000000..c8838c5
--- /dev/null
+++ b/unittests/VMCore/VerifierTest.cpp
@@ -0,0 +1,44 @@
+//===- llvm/unittest/VMCore/VerifierTest.cpp - Verifier unit tests --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Analysis/Verifier.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+TEST(VerifierTest, Branch_i1) {
+ LLVMContext &C = getGlobalContext();
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
+ Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage);
+ BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
+ BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
+ ReturnInst::Create(C, Exit);
+
+ // To avoid triggering an assertion in BranchInst::Create, we first create
+ // a branch with an 'i1' condition ...
+
+ Constant *False = ConstantInt::getFalse(C);
+ BranchInst *BI = BranchInst::Create(Exit, Exit, False, Entry);
+
+ // ... then use setOperand to redirect it to a value of different type.
+
+ Constant *Zero32 = ConstantInt::get(IntegerType::get(C, 32), 0);
+ BI->setOperand(0, Zero32);
+
+ EXPECT_TRUE(verifyFunction(*F, ReturnStatusAction));
+}
+
+}
+}