Verifier: Call verifyModule() from llc and opt
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 27 Mar 2015 22:04:28 +0000 (22:04 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 27 Mar 2015 22:04:28 +0000 (22:04 +0000)
Change `llc` and `opt` to run `verifyModule()`.  This ensures that we
check the full module before `FunctionPass::doInitialization()` ever
gets called (I was getting crashes in `DwarfDebug` instead of verifier
failures when testing a WIP patch that checks operands of compile
units).  In `opt`, also move up debug-info-stripping so that it still
runs before verification.

There was a fair bit of broken code that was sitting in tree.
Interestingly, some were cases of a `select` that referred to itself in
`-instcombine` tests (apparently an intermediate result).  I split them
off to `*-noverify.ll` tests with RUN lines like this:

    opt < %s -S -disable-verify -instcombine | opt -S | FileCheck %s

This avoids verifying the input file (so we can get the broken code into
`-instcombine), but still verifies the output with a second call to
`opt` (to verify that `-instcombine` will clean it up like it should).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233432 91177308-0d34-0410-b5e6-96231b3b80d8

18 files changed:
test/Transforms/DeadStoreElimination/simple.ll
test/Transforms/GlobalOpt/blockaddress.ll
test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll
test/Transforms/Inline/2003-09-22-PHINodeInlineFail.ll
test/Transforms/Inline/2003-09-22-PHINodesInExceptionDest.ll
test/Transforms/InstCombine/call-intrinsics.ll
test/Transforms/InstCombine/objsize-noverify.ll [new file with mode: 0644]
test/Transforms/InstCombine/objsize.ll
test/Transforms/InstCombine/select-crash-noverify.ll [new file with mode: 0644]
test/Transforms/InstCombine/select-crash.ll
test/Transforms/InstCombine/select.ll
test/Transforms/InstCombine/vec_demanded_elts.ll
test/Transforms/LoopSimplify/dup-preds.ll
test/Transforms/LowerInvoke/2003-12-10-Crash.ll
test/Transforms/ObjCARC/move-and-merge-autorelease.ll
test/Transforms/SimplifyCFG/UnreachableEliminate.ll
tools/llc/llc.cpp
tools/opt/opt.cpp

index dd1443e77e4dd7d259b48a5bbe1f9a9278d98a18..2ffe0539098e190b422ea16bae586266b7bad371 100644 (file)
@@ -3,7 +3,7 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
 
 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
-declare i8* @llvm.init.trampoline(i8*, i8*, i8*)
+declare void @llvm.init.trampoline(i8*, i8*, i8*)
 
 define void @test1(i32* %Q, i32* %P) {
         %DEAD = load i32, i32* %Q
@@ -132,7 +132,7 @@ define void @test11() {
        %storage = alloca [10 x i8], align 16           ; <[10 x i8]*> [#uses=1]
 ; CHECK-NOT: alloca
        %cast = getelementptr [10 x i8], [10 x i8]* %storage, i32 0, i32 0              ; <i8*> [#uses=1]
-       %tramp = call i8* @llvm.init.trampoline( i8* %cast, i8* bitcast (void ()* @test11f to i8*), i8* null )          ; <i8*> [#uses=1]
+       call void @llvm.init.trampoline( i8* %cast, i8* bitcast (void ()* @test11f to i8*), i8* null )          ; <i8*> [#uses=1]
 ; CHECK-NOT: trampoline
        ret void
 ; CHECK: ret void
index f7f830869b84916f71791a88f2a4910f10d64d46..12e09fcd48151f2409ab9f412832afef866595c7 100644 (file)
@@ -13,6 +13,9 @@ define void @f() {
 }
 
 define void @g() {
+entry:
+  br label %here
+
 ; CHECK-LABEL: @g(
 
 here:
index a0b1e84a8616dcc617e7767c5681b651dddf1d50..402ae8cc05d0ab9cf24ea4cb3301cecaaee65613 100644 (file)
@@ -31,7 +31,8 @@ loop:
   br i1 %cmp, label %loop, label %exit
 
 exit:
-  ret i8 %snext
+  %ret = phi i8 [0, %loopguard], [%snext, %loop]
+  ret i8 %ret
 }
 
 ; CHECK-LABEL: @testptrptr(
@@ -56,7 +57,8 @@ loop:
   br i1 %cmp, label %loop, label %exit
 
 exit:
-  ret i8 %snext
+  %ret = phi i8 [0, %loopguard], [%snext, %loop]
+  ret i8 %ret
 }
 
 ; CHECK-LABEL: @testnullptrint(
@@ -86,7 +88,8 @@ loop:
   br i1 %cmp, label %loop, label %exit
 
 exit:
-  ret i8 %snext
+  %ret = phi i8 [0, %loopguard], [%snext, %loop]
+  ret i8 %ret
 }
 
 ; CHECK-LABEL: @testptrint(
@@ -116,7 +119,8 @@ loop:
   br i1 %cmp, label %loop, label %exit
 
 exit:
-  ret i8 %snext
+  %ret = phi i8 [0, %loopguard], [%snext, %loop]
+  ret i8 %ret
 }
 
 ; IV and BECount have two different pointer types here.
index b8ca56050dcab459751c4d9aaaa0570891147cc8..df0b472bb2a51fc00ee5b827f58d34dedc9f0aed 100644 (file)
@@ -9,7 +9,7 @@ LongJmpBlkPost:
         ret i32 0
 
 LongJmpBlkPre:
-        %i.3 = phi i32 [ 0, %entry ], [ 0, %entry ]             ; <i32> [#uses=0]
+        %i.3 = phi i32 [ 0, %entry ]
         %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
                  cleanup
         ret i32 0
index 9af93325f1422b79e89084c68d64c0fb74e0ae71..d5416a205979a675551cb69fc031aa1da2a664b4 100644 (file)
@@ -9,7 +9,7 @@ Call2Invoke:            ; preds = %entry
         br label %exit
 
 LongJmpBlkPre:          ; preds = %Call2Invoke, %entry
-        %i.3 = phi i32 [ 0, %entry ], [ 0, %Call2Invoke ]               ; <i32> [#uses=0]
+        %i.3 = phi i32 [ 0, %entry ]
         %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
                  cleanup
         br label %exit
index f9d108058063c5fa073345b8c560bcfe00da3ee8..3e37a71e1bf60af67ecc78da66d71338bbaba7ed 100644 (file)
@@ -3,17 +3,17 @@
 @X = global i8 0                ; <i8*> [#uses=3]
 @Y = global i8 12               ; <i8*> [#uses=2]
 
-declare void @llvm.memmove.i32(i8*, i8*, i32, i32)
+declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
 
-declare void @llvm.memcpy.i32(i8*, i8*, i32, i32)
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
 
-declare void @llvm.memset.i32(i8*, i8, i32, i32)
+declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1)
 
 define void @zero_byte_test() {
         ; These process zero bytes, so they are a noop.
-        call void @llvm.memmove.i32( i8* @X, i8* @Y, i32 0, i32 100 )
-        call void @llvm.memcpy.i32( i8* @X, i8* @Y, i32 0, i32 100 )
-        call void @llvm.memset.i32( i8* @X, i8 123, i32 0, i32 100 )
+        call void @llvm.memmove.p0i8.p0i8.i32( i8* @X, i8* @Y, i32 0, i32 128, i1 false )
+        call void @llvm.memcpy.p0i8.p0i8.i32( i8* @X, i8* @Y, i32 0, i32 128, i1 false )
+        call void @llvm.memset.p0i8.i32( i8* @X, i8 123, i32 0, i32 128, i1 false )
         ret void
 }
 
diff --git a/test/Transforms/InstCombine/objsize-noverify.ll b/test/Transforms/InstCombine/objsize-noverify.ll
new file mode 100644 (file)
index 0000000..7e469bd
--- /dev/null
@@ -0,0 +1,43 @@
+; Test objectsize bounds checking that won't verify until after -instcombine.
+; RUN: opt < %s -disable-verify -instcombine -S | opt -S | FileCheck %s
+; We need target data to get the sizes of the arrays and structures.
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+
+declare i32 @llvm.objectsize.i32.p0i8(i8*, i1) nounwind readonly
+
+; CHECK-LABEL: @PR13390(
+define i32 @PR13390(i1 %bool, i8* %a) {
+entry:
+  %cond = or i1 %bool, true
+  br i1 %cond, label %return, label %xpto
+
+xpto:
+  %select = select i1 %bool, i8* %select, i8* %a
+  %select2 = select i1 %bool, i8* %a, i8* %select2
+  %0 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select, i1 true)
+  %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select2, i1 true)
+  %2 = add i32 %0, %1
+; CHECK: ret i32 undef
+  ret i32 %2
+
+return:
+  ret i32 42
+}
+
+; CHECK-LABEL: @PR13621(
+define i32 @PR13621(i1 %bool) nounwind {
+entry:
+  %cond = or i1 %bool, true
+  br i1 %cond, label %return, label %xpto
+
+; technically reachable, but this malformed IR may appear as a result of constant propagation
+xpto:
+  %gep2 = getelementptr i8, i8* %gep, i32 1
+  %gep = getelementptr i8, i8* %gep2, i32 1
+  %o = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 true)
+; CHECK: ret i32 undef
+  ret i32 %o
+
+return:
+  ret i32 7
+}
index 3125458549d64a64b7b9c054caa1a34193ef9dcc..335a816e9ecead92c5e19c12e88fb9ec72bd2e2a 100644 (file)
@@ -219,43 +219,6 @@ define i32 @test13(i8** %esc) {
   ret i32 %1
 }
 
-; CHECK-LABEL: @PR13390(
-define i32 @PR13390(i1 %bool, i8* %a) {
-entry:
-  %cond = or i1 %bool, true
-  br i1 %cond, label %return, label %xpto
-
-xpto:
-  %select = select i1 %bool, i8* %select, i8* %a
-  %select2 = select i1 %bool, i8* %a, i8* %select2
-  %0 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select, i1 true)
-  %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select2, i1 true)
-  %2 = add i32 %0, %1
-; CHECK: ret i32 undef
-  ret i32 %2
-
-return:
-  ret i32 42
-}
-
-; CHECK-LABEL: @PR13621(
-define i32 @PR13621(i1 %bool) nounwind {
-entry:
-  %cond = or i1 %bool, true
-  br i1 %cond, label %return, label %xpto
-
-; technically reachable, but this malformed IR may appear as a result of constant propagation
-xpto:
-  %gep2 = getelementptr i8, i8* %gep, i32 1
-  %gep = getelementptr i8, i8* %gep2, i32 1
-  %o = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 true)
-; CHECK: ret i32 undef
-  ret i32 %o
-
-return:
-  ret i32 7
-}
-
 @globalalias = internal alias [60 x i8]* @a
 
 ; CHECK-LABEL: @test18(
diff --git a/test/Transforms/InstCombine/select-crash-noverify.ll b/test/Transforms/InstCombine/select-crash-noverify.ll
new file mode 100644 (file)
index 0000000..4a366aa
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: opt < %s -disable-verify -instcombine -S | opt -S | FileCheck %s
+; Formerly crashed, PR8490.
+
+; CHECK-LABEL: @test3(
+define i32 @test3(i1 %bool, i32 %a) {
+entry:
+  %cond = or i1 %bool, true
+  br i1 %cond, label %return, label %xpto
+
+; technically reachable, but this malformed IR may appear as a result of constant propagation
+xpto:
+  %select = select i1 %bool, i32 %a, i32 %select
+  %select2 = select i1 %bool, i32 %select2, i32 %a
+  %sum = add i32 %select, %select2
+  ret i32 %sum
+
+return:
+  ret i32 7
+}
index 77446cd8ba0233e57b9f550b677fdf96e8210e18..991635b63aa8865db2cf99ea01550848efc7a495 100644 (file)
@@ -30,20 +30,3 @@ define <4 x float> @foo(i1 %b, <4 x float> %x, <4 x float> %y, <4 x float> %z) {
   %sel = select i1 %b, <4 x float> %a, <4 x float> %sub 
   ret <4 x float> %sel
 }
-
-; CHECK-LABEL: @test3(
-define i32 @test3(i1 %bool, i32 %a) {
-entry:
-  %cond = or i1 %bool, true
-  br i1 %cond, label %return, label %xpto
-
-; technically reachable, but this malformed IR may appear as a result of constant propagation
-xpto:
-  %select = select i1 %bool, i32 %a, i32 %select
-  %select2 = select i1 %bool, i32 %select2, i32 %a
-  %sum = add i32 %select, %select2
-  ret i32 %sum
-
-return:
-  ret i32 7
-}
index e4cc6f58c05a275e07cc3aa8cc080e245b40b1ba..ef122c92092da662ccabe18c3eb86425fdc93c5b 100644 (file)
@@ -423,11 +423,11 @@ jump:
   %c = or i1 false, false
   br label %ret 
 ret:
-  %a = phi i1 [true, %jump], [%c, %entry]
-  %b = select i1 %a, i32 10, i32 20
+  %a = phi i1 [true, %entry], [%c, %jump]
+  %b = select i1 %a, i32 20, i32 10
   ret i32 %b
 ; CHECK-LABEL: @test26(
-; CHECK: %a = phi i32 [ 10, %jump ], [ 20, %entry ]
+; CHECK: %a = phi i32 [ 20, %entry ], [ 10, %jump ]
 ; CHECK-NEXT: ret i32 %a
 }
 
index 8a8b834fa9e7668ef3a6ea168778321529dd9cc7..4245c7a3c134e690ddac8ebe219a857a51f99560 100644 (file)
@@ -350,19 +350,19 @@ define <8 x float> @test_vpermilvar_ps_256(<8 x float> %v) {
   ret <8 x float> %a
 }
 
-declare <2 x double> @llvm.x86.avx.vpermilvar.pd(<2 x double>, <2 x i32>)
+declare <2 x double> @llvm.x86.avx.vpermilvar.pd(<2 x double>, <2 x i64>)
 define <2 x double> @test_vpermilvar_pd(<2 x double> %v) {
 ; CHECK-LABEL: @test_vpermilvar_pd(
 ; CHECK: shufflevector <2 x double> %v, <2 x double> undef, <2 x i32> <i32 1, i32 0>
-  %a = tail call <2 x double> @llvm.x86.avx.vpermilvar.pd(<2 x double> %v, <2 x i32> <i32 2, i32 0>)
+  %a = tail call <2 x double> @llvm.x86.avx.vpermilvar.pd(<2 x double> %v, <2 x i64> <i64 2, i64 0>)
   ret <2 x double> %a
 }
 
-declare <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double>, <4 x i32>)
+declare <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double>, <4 x i64>)
 define <4 x double> @test_vpermilvar_pd_256(<4 x double> %v) {
 ; CHECK-LABEL: @test_vpermilvar_pd_256(
 ; CHECK: shufflevector <4 x double> %v, <4 x double> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
-  %a = tail call <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double> %v, <4 x i32> <i32 3, i32 1, i32 2, i32 0>)
+  %a = tail call <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double> %v, <4 x i64> <i64 3, i64 1, i64 2, i64 0>)
   ret <4 x double> %a
 }
 
@@ -383,14 +383,14 @@ define <8 x float> @test_vpermilvar_ps_256_zero(<8 x float> %v) {
 define <2 x double> @test_vpermilvar_pd_zero(<2 x double> %v) {
 ; CHECK-LABEL: @test_vpermilvar_pd_zero(
 ; CHECK: shufflevector <2 x double> %v, <2 x double> undef, <2 x i32> zeroinitializer
-  %a = tail call <2 x double> @llvm.x86.avx.vpermilvar.pd(<2 x double> %v, <2 x i32> zeroinitializer)
+  %a = tail call <2 x double> @llvm.x86.avx.vpermilvar.pd(<2 x double> %v, <2 x i64> zeroinitializer)
   ret <2 x double> %a
 }
 
 define <4 x double> @test_vpermilvar_pd_256_zero(<4 x double> %v) {
 ; CHECK-LABEL: @test_vpermilvar_pd_256_zero(
 ; CHECK: shufflevector <4 x double> %v, <4 x double> undef, <4 x i32> <i32 0, i32 0, i32 2, i32 2>
-  %a = tail call <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double> %v, <4 x i32> zeroinitializer)
+  %a = tail call <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double> %v, <4 x i64> zeroinitializer)
   ret <4 x double> %a
 }
 
index 3d1f1499b11cf244d79966651d520096c2d2ebcb..c9253fa51a65fa90ba67e1d4fb8977805e2d442f 100644 (file)
@@ -28,7 +28,7 @@ for.body305:                                      ; preds = %for.body305, %if.th
   br label %for.body305
 
 for.body344:                                      ; preds = %for.body344, %for.body276.lr.ph, %for.body276.lr.ph
-  %indvar = phi i64 [ %indvar.next, %for.body344 ], [ 0, %for.body276.lr.ph ]
+  %indvar = phi i64 [ %indvar.next, %for.body344 ], [ 0, %for.body276.lr.ph ], [ 0, %for.body276.lr.ph ]
   %indvars.iv552 = phi i64 [ %indvars.iv.next553, %for.body344 ], [ 0, %for.body276.lr.ph ], [ 0, %for.body276.lr.ph ]
   %indvars.iv.next553 = add nuw nsw i64 %indvars.iv552, 1
   %indvar.next = add i64 %indvar, 1
index 31f3d42225ab67808652c5b7fd2ca28de6e6f611..fca8e868018aba492edfcc1f837decf9bd3b68f0 100644 (file)
@@ -15,8 +15,11 @@ invoke_cont.0:               ; preds = %then
                        to label %try_exit unwind label %try_catch
 try_catch:             ; preds = %invoke_cont.0, %then
        %__tmp.0 = phi i32* [ null, %invoke_cont.0 ], [ null, %then ]           ; <i32*> [#uses=0]
+  %res = landingpad { i8* } personality i32 (...)* @__gxx_personality_v0
+          cleanup
        ret void
 try_exit:              ; preds = %invoke_cont.0
        ret void
 }
 
+declare i32 @__gxx_personality_v0(...)
index 5d19f355be3239968e35835c3a07b3e8d904ea3c..0a68541d9350a5a91fcc68d78848a09a4f690c91 100644 (file)
@@ -99,9 +99,9 @@ bb81:                                             ; preds = %bb, %bb76
   %tmp10.1 = phi %0* [ %tmp10.0, %bb76 ], [ null, %bb ]
   %tmp83 = bitcast %0* %tmp10.1 to i8*
   %tmp84 = call i8* @objc_retain(i8* %tmp83) nounwind
-  %tmp88 = bitcast i8* %tmp87 to %0*
   call void @objc_release(i8* %tmp23) nounwind
   %tmp87 = call i8* @objc_autorelease(i8* %tmp84) nounwind
+  %tmp88 = bitcast i8* %tmp87 to %0*
   %tmp92 = bitcast %0* %tmp10.1 to i8*
   call void @objc_release(i8* %tmp92) nounwind
   ret %0* %tmp88
index 22b144b5cb80cbedf9ed38f22fbc28a29a276a06..8718c552c693aff74e3fdf903a456a794831fa75 100644 (file)
@@ -22,11 +22,15 @@ entry:
         invoke void @test2( )
                         to label %N unwind label %U
 U:
+  %res = landingpad { i8* } personality i32 (...)* @__gxx_personality_v0
+          cleanup
         unreachable
 N:
         ret void
 }
 
+declare i32 @__gxx_personality_v0(...)
+
 define i32 @test3(i32 %v) {
 ; CHECK-LABEL: @test3(
 ; CHECK: entry:
index 55a45dca2e8cce665368ce3cacd4c58f7268c636..fa8d2688dd2e0bd54db786dfa4c5bd27a5b7c84b 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Pass.h"
@@ -225,6 +226,14 @@ static int compileModule(char **argv, LLVMContext &Context) {
       return 1;
     }
 
+    // Verify module immediately to catch problems before doInitialization() is
+    // called on any passes.
+    if (!NoVerify && verifyModule(*M, &errs())) {
+      errs() << argv[0] << ": " << InputFilename
+             << ": error: does not verify\n";
+      return 1;
+    }
+
     // If we are supposed to override the target triple, do so now.
     if (!TargetTriple.empty())
       M->setTargetTriple(Triple::normalize(TargetTriple));
index c1e120af5407762f2526f0121ffe4da9fd1855cc..86fbed700365dc4b01c1c9be59da6d2c8b47c6da 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/Bitcode/BitcodeWriterPass.h"
 #include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/LegacyPassNameParser.h"
@@ -345,6 +346,18 @@ int main(int argc, char **argv) {
     return 1;
   }
 
+  // Strip debug info before running the verifier.
+  if (StripDebug)
+    StripDebugInfo(*M);
+
+  // Immediately run the verifier to catch any problems before starting up the
+  // pass pipelines.  Otherwise we can crash on broken code during
+  // doInitialization().
+  if (!NoVerify && verifyModule(*M, &errs())) {
+    errs() << argv[0] << ": " << InputFilename << ": error: does not verify\n";
+    return 1;
+  }
+
   // If we are supposed to override the target triple, do so now.
   if (!TargetTriple.empty())
     M->setTargetTriple(Triple::normalize(TargetTriple));
@@ -449,10 +462,6 @@ int main(int argc, char **argv) {
     NoOutput = true;
   }
 
-  // If the -strip-debug command line option was specified, add it.
-  if (StripDebug)
-    addPass(Passes, createStripSymbolsPass(true));
-
   // Create a new optimization pass for each one specified on the command line
   for (unsigned i = 0; i < PassList.size(); ++i) {
     if (StandardLinkOpts &&