mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-20 12:31:40 +00:00
[InstCombine] Fix regression introduced at r227197.
This patch fixes a problem I accidentally introduced in an instruction combine on select instructions added at r227197. That revision taught the instruction combiner how to fold a cttz/ctlz followed by a icmp plus select into a single cttz/ctlz with flag 'is_zero_undef' cleared. However, the new rule added at r227197 would have produced wrong results in the case where a cttz/ctlz with flag 'is_zero_undef' cleared was follwed by a zero-extend or truncate. In that case, the folded instruction would have been inserted in a wrong location thus leaving the CFG in an inconsistent state. This patch fixes the problem and add two reproducible test cases to existing test 'InstCombine/select-cmp-cttz-ctlz.ll'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229124 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3229c883b9
commit
d25126faae
@ -482,16 +482,12 @@ static Value *foldSelectCttzCtlz(ICmpInst *ICI, Value *TrueVal, Value *FalseVal,
|
||||
match(Count, m_Intrinsic<Intrinsic::ctlz>(m_Specific(CmpLHS)))) {
|
||||
IntrinsicInst *II = cast<IntrinsicInst>(Count);
|
||||
IRBuilder<> Builder(II);
|
||||
if (cast<ConstantInt>(II->getArgOperand(1))->isOne()) {
|
||||
// Explicitly clear the 'undef_on_zero' flag.
|
||||
IntrinsicInst *NewI = cast<IntrinsicInst>(II->clone());
|
||||
Type *Ty = NewI->getArgOperand(1)->getType();
|
||||
NewI->setArgOperand(1, Constant::getNullValue(Ty));
|
||||
Builder.Insert(NewI);
|
||||
Count = NewI;
|
||||
}
|
||||
|
||||
return Builder.CreateZExtOrTrunc(Count, ValueOnZero->getType());
|
||||
// Explicitly clear the 'undef_on_zero' flag.
|
||||
IntrinsicInst *NewI = cast<IntrinsicInst>(II->clone());
|
||||
Type *Ty = NewI->getArgOperand(1)->getType();
|
||||
NewI->setArgOperand(1, Constant::getNullValue(Ty));
|
||||
Builder.Insert(NewI);
|
||||
return Builder.CreateZExtOrTrunc(NewI, ValueOnZero->getType());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -292,6 +292,33 @@ entry:
|
||||
ret i16 %cond
|
||||
}
|
||||
|
||||
define i64 @select_bug1(i32 %x) {
|
||||
; CHECK-LABEL: @select_bug1(
|
||||
; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
|
||||
; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
|
||||
; CHECK-NEXT: ret i64 [[VAR2]]
|
||||
entry:
|
||||
%0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
|
||||
%conv = zext i32 %0 to i64
|
||||
%tobool = icmp ne i32 %x, 0
|
||||
%cond = select i1 %tobool, i64 %conv, i64 32
|
||||
ret i64 %cond
|
||||
}
|
||||
|
||||
define i16 @select_bug2(i32 %x) {
|
||||
; CHECK-LABEL: @select_bug2(
|
||||
; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
|
||||
; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
|
||||
; CHECK-NEXT: ret i16 [[VAR2]]
|
||||
entry:
|
||||
%0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
|
||||
%conv = trunc i32 %0 to i16
|
||||
%tobool = icmp ne i32 %x, 0
|
||||
%cond = select i1 %tobool, i16 %conv, i16 32
|
||||
ret i16 %cond
|
||||
}
|
||||
|
||||
|
||||
declare i16 @llvm.ctlz.i16(i16, i1)
|
||||
declare i32 @llvm.ctlz.i32(i32, i1)
|
||||
declare i64 @llvm.ctlz.i64(i64, i1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user