New user self-registration is disabled due to spam. For an account please email bugs-admin@lists.llvm.org with your e-mail address and full name.

Bug 42962 - foldICmpBinOp => Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"
Summary: foldICmpBinOp => Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatib...
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Scalar Optimizations (show other bugs)
Version: trunk
Hardware: PC Windows NT
: P enhancement
Assignee: Roman Lebedev
URL:
Keywords:
Depends on:
Blocks: release-9.0.0
  Show dependency tree
 
Reported: 2019-08-12 01:45 PDT by bjorn.a.pettersson
Modified: 2019-08-13 04:57 PDT (History)
5 users (show)

See Also:
Fixed By Commit(s): r368554


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description bjorn.a.pettersson 2019-08-12 01:45:53 PDT
Given this IR (foo.ll):

;--------------------------------------------------------------------
@f.a = internal global i16 0

define dso_local void @f() local_unnamed_addr {
entry:
  %0 = load i16, i16* @f.a
  %shr = ashr i16 %0, 1
  %shr1 = ashr i16 %shr, zext (i1 icmp ne (i16 ptrtoint (i16* @f.a to i16), i16 1) to i16)
  %and = and i16 %shr1, 1
  %tobool = icmp ne i16 %and, 0
  br i1 %tobool, label %land.rhs, label %land.end

land.rhs:
  br label %land.end

land.end:
  ret void
}
;--------------------------------------------------------------------

we hit an assertion when running instcombine.

> opt -instcombine -o - foo.ll -S
opt: ../include/llvm/Support/Casting.h:264: typename cast_retty<X, Y *>::ret_type llvm::cast(Y *) [X = llvm::BinaryOperator, Y = llvm::Value]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
Stack dump:
0.      Program arguments: opt -instcombine -o - foo.ll -S 
1.      Running pass 'Function Pass Manager' on module 'foo.ll'.
2.      Running pass 'Combine redundant instructions' on function '@f'
 #0 0x00000000025455a4 PrintStackTraceSignalHandler(void*) (opt+0x25455a4)
 #1 0x000000000254330e llvm::sys::RunSignalHandlers() (opt+0x254330e)
 #2 0x00000000025459a8 SignalHandler(int) (opt+0x25459a8)
 #3 0x0000003ba280f7e0 __restore_rt (/lib64/libpthread.so.0+0x3ba280f7e0)
 #4 0x0000003ba24324f5 raise (/lib64/libc.so.6+0x3ba24324f5)
 #5 0x0000003ba2433cd5 abort (/lib64/libc.so.6+0x3ba2433cd5)
 #6 0x0000003ba242b66e __assert_fail_base (/lib64/libc.so.6+0x3ba242b66e)
 #7 0x0000003ba242b730 __assert_perror_fail (/lib64/libc.so.6+0x3ba242b730)
 #8 0x00000000020d3647 llvm::InstCombiner::foldICmpBinOp(llvm::ICmpInst&) (opt+0x20d3647)
 #9 0x00000000020d9f3b llvm::InstCombiner::visitICmpInst(llvm::ICmpInst&) (opt+0x20d9f3b)
#10 0x00000000020640af llvm::InstCombiner::run() (opt+0x20640af)
#11 0x0000000002066491 combineInstructionsOverFunction(llvm::Function&, llvm::InstCombineWorklist&, llvm::AAResults*, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::DominatorTree&, llvm::TargetTransformInfo const&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::ProfileSummaryInfo*, bool, llvm::LoopInfo*) (opt+0x2066491)
#12 0x0000000002066cee llvm::InstructionCombiningPass::runOnFunction(llvm::Function&) (opt+0x2066cee)
#13 0x0000000001edf873 llvm::FPPassManager::runOnFunction(llvm::Function&) (opt+0x1edf873)
#14 0x0000000001edfb83 llvm::FPPassManager::runOnModule(llvm::Module&) (opt+0x1edfb83)
#15 0x0000000001ee01ed llvm::legacy::PassManagerImpl::run(llvm::Module&) (opt+0x1ee01ed)
#16 0x000000000080e9b7 main (opt+0x80e9b7)
#17 0x0000003ba241ed20 __libc_start_main (/lib64/libc.so.6+0x3ba241ed20)
#18 0x00000000007f5ff9 _start (opt+0x7f5ff9)
Abort (core dumped)


Afaict it started to happen after:

commit 72b8d41ce811fa1a20711e0619d4a5307a754e57
Author: Roman Lebedev <lebedev.ri@gmail.com>
Date:   Mon Jul 1 15:55:15 2019 +0000

    [InstCombine] Shift amount reassociation in bittest (PR42399)
    
    Summary:
    Given pattern:
    `icmp eq/ne (and ((x shift Q), (y oppositeshift K))), 0`
    we should move shifts to the same hand of 'and', i.e. rewrite as
    `icmp eq/ne (and (x shift (Q+K)), y), 0`  iff `(Q+K) u< bitwidth(x)`
    
    It might be tempting to not restrict this to situations where we know
    we'd fold two shifts together, but i'm not sure what rules should there be
    to avoid endless combine loops.
    
    We pick the same shift that was originally used to shift the variable we picked to shift:
    https://rise4fun.com/Alive/6x1v
    
    Should fix [[ https://bugs.llvm.org/show_bug.cgi?id=42399 | PR42399]].
    
    Reviewers: spatel, nikic, RKSimon
    
    Reviewed By: spatel
    
    Subscribers: llvm-commits
    
    Tags: #llvm
    
    Differential Revision: https://reviews.llvm.org/D63829
    
    llvm-svn: 364791
Comment 1 Roman Lebedev 2019-08-12 04:29:07 PDT
Sigh, that pattern again :/
r368554, please cherry-pick.
Comment 2 bjorn.a.pettersson 2019-08-12 08:39:57 PDT
Thanks. Fix works for me.

Had to cherry-pick r368519 as well, since I was a few days behind trunk.
Comment 3 Hans Wennborg 2019-08-13 04:57:19 PDT
(In reply to Roman Lebedev from comment #1)
> Sigh, that pattern again :/
> r368554, please cherry-pick.

Merged together with r368517--r368519 (they looked safe enough) to release_90 in r368673.