Skip to content

Commit 07c18a0

Browse files
committed
[InstSimplify] Fix select bit test miscompile with disjoint
The select condition ensures the disjointness here. The transform is not valid without dropping the flag, which InstSimplify can't do.
1 parent c89553a commit 07c18a0

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4447,14 +4447,22 @@ static Value *simplifySelectBitTest(Value *TrueVal, Value *FalseVal, Value *X,
44474447
// (X & Y) == 0 ? X | Y : X --> X | Y
44484448
// (X & Y) != 0 ? X | Y : X --> X
44494449
if (FalseVal == X && match(TrueVal, m_Or(m_Specific(X), m_APInt(C))) &&
4450-
*Y == *C)
4450+
*Y == *C) {
4451+
// We can't return the or if it has the disjoint flag.
4452+
if (TrueWhenUnset && cast<PossiblyDisjointInst>(TrueVal)->isDisjoint())
4453+
return nullptr;
44514454
return TrueWhenUnset ? TrueVal : FalseVal;
4455+
}
44524456

44534457
// (X & Y) == 0 ? X : X | Y --> X
44544458
// (X & Y) != 0 ? X : X | Y --> X | Y
44554459
if (TrueVal == X && match(FalseVal, m_Or(m_Specific(X), m_APInt(C))) &&
4456-
*Y == *C)
4460+
*Y == *C) {
4461+
// We can't return the or if it has the disjoint flag.
4462+
if (!TrueWhenUnset && cast<PossiblyDisjointInst>(FalseVal)->isDisjoint())
4463+
return nullptr;
44574464
return TrueWhenUnset ? TrueVal : FalseVal;
4465+
}
44584466
}
44594467

44604468
return nullptr;

llvm/test/Transforms/InstSimplify/select.ll

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,12 @@ define i32 @test4(i32 %X) {
174174
ret i32 %cond
175175
}
176176

177-
; FIXME: This is a miscompile.
178177
define i32 @test4_disjoint(i32 %X) {
179178
; CHECK-LABEL: @test4_disjoint(
180-
; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X:%.*]], -2147483648
181-
; CHECK-NEXT: ret i32 [[OR]]
179+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
180+
; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X]], -2147483648
181+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[OR]]
182+
; CHECK-NEXT: ret i32 [[COND]]
182183
;
183184
%cmp = icmp slt i32 %X, 0
184185
%or = or disjoint i32 %X, -2147483648
@@ -270,11 +271,12 @@ define i32 @test9(i32 %X) {
270271
ret i32 %cond
271272
}
272273

273-
; FIXME: This is a miscompile.
274274
define i32 @test9_disjoint(i32 %X) {
275275
; CHECK-LABEL: @test9_disjoint(
276-
; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X:%.*]], -2147483648
277-
; CHECK-NEXT: ret i32 [[OR]]
276+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
277+
; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X]], -2147483648
278+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[X]]
279+
; CHECK-NEXT: ret i32 [[COND]]
278280
;
279281
%cmp = icmp sgt i32 %X, -1
280282
%or = or disjoint i32 %X, -2147483648

0 commit comments

Comments
 (0)