Skip to content

Commit d3dad7a

Browse files
authored
[InstCombine] Fix miscompilation caused by #90436 (#91133)
Proof: https://alive2.llvm.org/ce/z/iRnJ4i Fixes #91127.
1 parent 30367cb commit d3dad7a

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,6 +1510,7 @@ InstCombinerImpl::foldICmpTruncWithTruncOrExt(ICmpInst &Cmp,
15101510
std::swap(X, Y);
15111511
Pred = Cmp.getSwappedPredicate(Pred);
15121512
}
1513+
YIsSExt = !(NoWrapFlags & TruncInst::NoUnsignedWrap);
15131514
}
15141515
// Try to match icmp (trunc nuw X), (zext Y)
15151516
else if (!Cmp.isSigned() &&

llvm/test/Transforms/InstCombine/icmp-of-trunc-ext.ll

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,3 +568,77 @@ define i1 @trunc_equality_both_sext(i32 %x, i8 %y) {
568568
%c = icmp ne i16 %xt, %ye
569569
ret i1 %c
570570
}
571+
572+
define i1 @test_eq1(i32 %x, i16 %y) {
573+
; CHECK-LABEL: @test_eq1(
574+
; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[Y:%.*]] to i32
575+
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[TMP1]], [[X:%.*]]
576+
; CHECK-NEXT: ret i1 [[COND]]
577+
;
578+
%conv1 = trunc nsw i32 %x to i8
579+
%conv2 = trunc nsw i16 %y to i8
580+
%cond = icmp eq i8 %conv1, %conv2
581+
ret i1 %cond
582+
}
583+
584+
; FIXME: It is weird that we generate truncs for test_eq2, but not for test_eq1.
585+
586+
define i1 @test_eq2(i32 %x, i16 %y) {
587+
; CHECK-LABEL: @test_eq2(
588+
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
589+
; CHECK-NEXT: [[COND:%.*]] = icmp eq i16 [[TMP1]], [[Y:%.*]]
590+
; CHECK-NEXT: ret i1 [[COND]]
591+
;
592+
%conv1 = trunc nsw i32 %x to i8
593+
%conv2 = trunc nsw i16 %y to i8
594+
%cond = icmp eq i8 %conv2, %conv1
595+
ret i1 %cond
596+
}
597+
598+
define i1 @test_ult(i32 %x, i16 %y) {
599+
; CHECK-LABEL: @test_ult(
600+
; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[Y:%.*]] to i32
601+
; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[TMP1]], [[X:%.*]]
602+
; CHECK-NEXT: ret i1 [[COND]]
603+
;
604+
%conv1 = trunc nsw i32 %x to i8
605+
%conv2 = trunc nsw i16 %y to i8
606+
%cond = icmp ult i8 %conv1, %conv2
607+
ret i1 %cond
608+
}
609+
610+
define i1 @test_slt(i32 %x, i16 %y) {
611+
; CHECK-LABEL: @test_slt(
612+
; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[Y:%.*]] to i32
613+
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[TMP1]], [[X:%.*]]
614+
; CHECK-NEXT: ret i1 [[COND]]
615+
;
616+
%conv1 = trunc nsw i32 %x to i8
617+
%conv2 = trunc nsw i16 %y to i8
618+
%cond = icmp slt i8 %conv1, %conv2
619+
ret i1 %cond
620+
}
621+
622+
define i1 @test_ult_nuw(i32 %x, i16 %y) {
623+
; CHECK-LABEL: @test_ult_nuw(
624+
; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[Y:%.*]] to i32
625+
; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[TMP1]], [[X:%.*]]
626+
; CHECK-NEXT: ret i1 [[COND]]
627+
;
628+
%conv1 = trunc nuw nsw i32 %x to i8
629+
%conv2 = trunc nuw nsw i16 %y to i8
630+
%cond = icmp ult i8 %conv1, %conv2
631+
ret i1 %cond
632+
}
633+
634+
define i1 @test_slt_nuw(i32 %x, i16 %y) {
635+
; CHECK-LABEL: @test_slt_nuw(
636+
; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[Y:%.*]] to i32
637+
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[TMP1]], [[X:%.*]]
638+
; CHECK-NEXT: ret i1 [[COND]]
639+
;
640+
%conv1 = trunc nuw nsw i32 %x to i8
641+
%conv2 = trunc nuw nsw i16 %y to i8
642+
%cond = icmp slt i8 %conv1, %conv2
643+
ret i1 %cond
644+
}

0 commit comments

Comments
 (0)