mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 00:11:00 +00:00
Verifier: Call verifyModule() from llc and opt
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
This commit is contained in:
parent
527745e789
commit
de89228dfb
@ -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
|
||||
|
@ -13,6 +13,9 @@ define void @f() {
|
||||
}
|
||||
|
||||
define void @g() {
|
||||
entry:
|
||||
br label %here
|
||||
|
||||
; CHECK-LABEL: @g(
|
||||
|
||||
here:
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
43
test/Transforms/InstCombine/objsize-noverify.ll
Normal file
43
test/Transforms/InstCombine/objsize-noverify.ll
Normal file
@ -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
|
||||
}
|
@ -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(
|
||||
|
19
test/Transforms/InstCombine/select-crash-noverify.ll
Normal file
19
test/Transforms/InstCombine/select-crash-noverify.ll
Normal file
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(...)
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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));
|
||||
|
@ -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 &&
|
||||
|
Loading…
Reference in New Issue
Block a user