This adds a simple transformation from icmp with poison constant to poison.
Comparing poison with something else is poison, so this is okay.
https://alive2.llvm.org/ce/z/e8iReb
https://alive2.llvm.org/ce/z/q4MurY
Type *ITy = GetCompareTy(LHS); // The return type.
+ // icmp poison, X -> poison
+ if (isa<PoisonValue>(RHS))
+ return PoisonValue::get(ITy);
+
// For EQ and NE, we can always pick a value for the undef to make the
// predicate pass or fail, so we can return undef.
// Matches behavior in llvm::ConstantFoldCompareInstruction.
define i32* @PR45084(i1 %cond) {
; CHECK-LABEL: @PR45084(
-; CHECK-NEXT: [[GEP:%.*]] = select i1 [[COND:%.*]], i32* getelementptr inbounds ([[STRUCT_F:%.*]], %struct.f* @g0, i64 0, i32 0), i32* getelementptr inbounds ([[STRUCT_F]], %struct.f* @g1, i64 0, i32 0), !prof !0
+; CHECK-NEXT: [[GEP:%.*]] = select i1 [[COND:%.*]], i32* getelementptr inbounds ([[STRUCT_F:%.*]], %struct.f* @g0, i64 0, i32 0), i32* getelementptr inbounds ([[STRUCT_F]], %struct.f* @g1, i64 0, i32 0), !prof [[PROF0:![0-9]+]]
; CHECK-NEXT: ret i32* [[GEP]]
;
%sel = select i1 %cond, %struct.f* @g0, %struct.f* @g1, !prof !0
; CHECK-LABEL: @test1_PR2274(
; CHECK-NEXT: [[Y:%.*]] = lshr i32 [[X:%.*]], 30
; CHECK-NEXT: [[R:%.*]] = udiv i32 [[Y]], [[G:%.*]]
-; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[R]] to i64
-; CHECK-NEXT: ret i64 [[TMP1]]
+; CHECK-NEXT: [[Z:%.*]] = zext i32 [[R]] to i64
+; CHECK-NEXT: ret i64 [[Z]]
;
%y = lshr i32 %x, 30
%r = udiv i32 %y, %g
; CHECK-LABEL: @test2_PR2274(
; CHECK-NEXT: [[Y:%.*]] = lshr i32 [[X:%.*]], 31
; CHECK-NEXT: [[R:%.*]] = udiv i32 [[Y]], [[V:%.*]]
-; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[R]] to i64
-; CHECK-NEXT: ret i64 [[TMP1]]
+; CHECK-NEXT: [[Z:%.*]] = zext i32 [[R]] to i64
+; CHECK-NEXT: ret i64 [[Z]]
;
%y = lshr i32 %x, 31
%r = udiv i32 %y, %v
; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4857
define i177 @ossfuzz_4857(i177 %X, i177 %Y) {
; CHECK-LABEL: @ossfuzz_4857(
-; CHECK-NEXT: store i1 false, i1* undef, align 1
; CHECK-NEXT: ret i177 0
;
%B5 = udiv i177 %Y, -1
ret i1 %cmp
}
-; TODO: these should return poison
-
define i1 @poison(i32 %x) {
; CHECK-LABEL: @poison(
-; CHECK-NEXT: ret i1 undef
+; CHECK-NEXT: ret i1 poison
;
%v = icmp eq i32 %x, poison
ret i1 %v
define i1 @poison2(i32 %x) {
; CHECK-LABEL: @poison2(
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: ret i1 poison
;
%v = icmp slt i32 %x, poison
ret i1 %v