[llvm] 07c18a0 - [InstSimplify] Fix select bit test miscompile with disjoint
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 07:55:52 PST 2023
Author: Nikita Popov
Date: 2023-11-30T16:55:32+01:00
New Revision: 07c18a05e2cb80e87b0c681c147a253565064f3e
URL: https://github.com/llvm/llvm-project/commit/07c18a05e2cb80e87b0c681c147a253565064f3e
DIFF: https://github.com/llvm/llvm-project/commit/07c18a05e2cb80e87b0c681c147a253565064f3e.diff
LOG: [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.
Added:
Modified:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/select.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index ad608702b859f79..9f3b3f25ec3f154 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4447,14 +4447,22 @@ static Value *simplifySelectBitTest(Value *TrueVal, Value *FalseVal, Value *X,
// (X & Y) == 0 ? X | Y : X --> X | Y
// (X & Y) != 0 ? X | Y : X --> X
if (FalseVal == X && match(TrueVal, m_Or(m_Specific(X), m_APInt(C))) &&
- *Y == *C)
+ *Y == *C) {
+ // We can't return the or if it has the disjoint flag.
+ if (TrueWhenUnset && cast<PossiblyDisjointInst>(TrueVal)->isDisjoint())
+ return nullptr;
return TrueWhenUnset ? TrueVal : FalseVal;
+ }
// (X & Y) == 0 ? X : X | Y --> X
// (X & Y) != 0 ? X : X | Y --> X | Y
if (TrueVal == X && match(FalseVal, m_Or(m_Specific(X), m_APInt(C))) &&
- *Y == *C)
+ *Y == *C) {
+ // We can't return the or if it has the disjoint flag.
+ if (!TrueWhenUnset && cast<PossiblyDisjointInst>(FalseVal)->isDisjoint())
+ return nullptr;
return TrueWhenUnset ? TrueVal : FalseVal;
+ }
}
return nullptr;
diff --git a/llvm/test/Transforms/InstSimplify/select.ll b/llvm/test/Transforms/InstSimplify/select.ll
index d0bb6c2613ef1b0..16901b888933875 100644
--- a/llvm/test/Transforms/InstSimplify/select.ll
+++ b/llvm/test/Transforms/InstSimplify/select.ll
@@ -174,11 +174,12 @@ define i32 @test4(i32 %X) {
ret i32 %cond
}
-; FIXME: This is a miscompile.
define i32 @test4_disjoint(i32 %X) {
; CHECK-LABEL: @test4_disjoint(
-; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X:%.*]], -2147483648
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X]], -2147483648
+; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[OR]]
+; CHECK-NEXT: ret i32 [[COND]]
;
%cmp = icmp slt i32 %X, 0
%or = or disjoint i32 %X, -2147483648
@@ -270,11 +271,12 @@ define i32 @test9(i32 %X) {
ret i32 %cond
}
-; FIXME: This is a miscompile.
define i32 @test9_disjoint(i32 %X) {
; CHECK-LABEL: @test9_disjoint(
-; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X:%.*]], -2147483648
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X]], -2147483648
+; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[X]]
+; CHECK-NEXT: ret i32 [[COND]]
;
%cmp = icmp sgt i32 %X, -1
%or = or disjoint i32 %X, -2147483648
More information about the llvm-commits
mailing list