[llvm] sext/zext instcombine (PR #67895)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 30 15:36:29 PDT 2023
https://github.com/elhewaty created https://github.com/llvm/llvm-project/pull/67895
- Add test coverage for sext/zext boolean additions
- [InstCombine] Fold comparison of adding two z/sext booleans
>From 57f5806ef1f587f01d5b08cf92fd11a974bd950e Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Sun, 1 Oct 2023 00:42:12 +0300
Subject: [PATCH 1/2] Add test coverage for sext/zext boolean additions
---
llvm/test/Transforms/InstCombine/icmp-add.ll | 792 +++++++++++++++++++
1 file changed, 792 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index a2d0c3eb39d69ec..ec8d7d14d3b51f7 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -5,6 +5,798 @@ declare void @use(i32)
; PR1949
+define i1 @cvt_icmp_0_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp eq i32 %i3, 0
+ ret i1 %i4
+}
+
+define i1 @cvt_icmp_1_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp eq i32 [[I3]], 1
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp eq i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @cvt_icmp_2_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 2
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_0_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 0
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_1_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 1
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 1
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_2_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 2
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_0_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 0
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_1_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
+; CHECK-NEXT: [[T:%.*]] = and i1 [[TMP0]], [[ARG1:%.*]]
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 1
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_2_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 2
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_0_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[TMP0]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ne i32 %i3, 0
+ ret i1 %i4
+}
+
+define i1 @cvt_icmp_1_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp ne i32 [[I3]], 1
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ne i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @cvt_icmp_2_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 2
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_0_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: ret i1 [[TMP0]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 0
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_1_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 1
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 1
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_2_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 2
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_0_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 0
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_1_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
+; CHECK-NEXT: [[T:%.*]] = or i1 [[TMP0]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 1
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_2_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 2
+ ret i1 %t
+}
+
+; test if zext i1 X + sext i1 Y converted to sext i1 X + zext i1 Y
+; and then processed
+
+define i1 @cvt_icmp_0_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 0
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_1_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
+; CHECK-NEXT: [[T:%.*]] = and i1 [[TMP0]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 1
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_2_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_eq(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp eq i32 %i3, 2
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_0_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 0
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_1_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
+; CHECK-NEXT: [[T:%.*]] = or i1 [[TMP0]], [[ARG1:%.*]]
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 1
+ ret i1 %t
+}
+
+define i1 @cvt_icmp_2_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_ne(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
+; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i, %i2
+ %t = icmp ne i32 %i3, 2
+ ret i1 %t
+}
+
+; test zext/zext additions with more than one use
+
+define i1 @test_cvt_icmp1(i1 %arg, i1 %arg1, ptr %p) {
+; CHECK-LABEL: @test_cvt_icmp1(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG]] to i32
+; CHECK-NEXT: store i32 [[I2]], ptr [[P:%.*]], align 4
+; CHECK-NEXT: [[I4:%.*]] = add nuw nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I4]], 1
+; CHECK-NEXT: ret i1 [[T]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg to i32
+ store i32 %i2, ptr %p
+ %i3 = load i32, ptr %p
+ %i4 = add i32 %i3, %i
+ %t = icmp eq i32 %i4, 1
+ ret i1 %t
+}
+
+define i1 @test_cvt_icmp2(i1 %arg, i1 %arg1, ptr %p) {
+; CHECK-LABEL: @test_cvt_icmp2(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: store i32 [[I2]], ptr [[P:%.*]], align 4
+; CHECK-NEXT: ret i1 false
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg to i32
+ store i32 %i2, ptr %p
+ %i3 = load i32, ptr %p
+ %i4 = add i32 %i3, %i
+ %t = icmp eq i32 %i4, 1
+ ret i1 %t
+}
+
+; tests for negative comparisons
+define i1 @test_cvt_icmp3(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp3(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: ret i1 false
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ult i32 %i3, 0
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp4(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp4(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[TMP0]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ugt i32 %i3, 0
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp5(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp5(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[TMP0]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp uge i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp6(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp6(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp ult i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ule i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp7(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp7(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp ugt i32 [[I3]], 1
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp sgt i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp8(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp8(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[TMP0]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp sge i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp9(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp9(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp slt i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp10(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp10(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp ult i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = zext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp sle i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp11(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp11(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp ugt i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ugt i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp12(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp12(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[TMP0]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp uge i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp13(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp13(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ult i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp14(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp14(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp ult i32 [[I3]], 3
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ule i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp15(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp15(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp sgt i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp16(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp16(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[I3]], 1
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp sge i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp17(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp17(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp slt i32 [[I3]], 2
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp slt i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp18(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp18(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp slt i32 [[I3]], 3
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = sext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp sle i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp19(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp19(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
+; CHECK-NEXT: [[I4:%.*]] = and i1 [[TMP0]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ugt i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp20(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp20(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp uge i32 %i3, 1
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp21(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp21(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true
+; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG_NOT]], [[ARG1:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ult i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp22(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp22(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
+; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
+; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I2]], [[I]]
+; CHECK-NEXT: [[I4:%.*]] = icmp ult i32 [[I3]], 3
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp ule i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp23(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp23(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: ret i1 false
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp sgt i32 %i3, 2
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp24(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp24(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
+; CHECK-NEXT: [[I4:%.*]] = or i1 [[TMP0]], [[ARG1:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp sge i32 %i3, 0
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp25(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp25(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
+; CHECK-NEXT: [[I4:%.*]] = and i1 [[TMP0]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp slt i32 %i3, 0
+ ret i1 %i4
+}
+
+define i1 @test_cvt_icmp26(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @test_cvt_icmp26(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: ret i1 true
+;
+bb:
+ %i = sext i1 %arg to i32
+ %i2 = zext i1 %arg1 to i32
+ %i3 = add i32 %i2, %i
+ %i4 = icmp sle i32 %i3, 1
+ ret i1 %i4
+}
+
define i1 @test1(i32 %a) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[A:%.*]], -5
>From 7cca836e722de44d9863fd073e8112be6d9e9164 Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Sun, 1 Oct 2023 01:35:26 +0300
Subject: [PATCH 2/2] [InstCombine] Fold comparison of adding two z/sext
booleans
---
.../InstCombine/InstCombineCompares.cpp | 104 +++++++++++++++++-
llvm/test/Transforms/InstCombine/icmp-add.ll | 100 +++++------------
2 files changed, 131 insertions(+), 73 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 9f034aba874a8c4..cb828d0a6fc2a37 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2900,14 +2900,114 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
BinaryOperator *Add,
const APInt &C) {
Value *Y = Add->getOperand(1);
+ Value *X = Add->getOperand(0);
+
+ Value *Op0 = X, *Op1 = Y;
+ const CmpInst::Predicate Pred = Cmp.getPredicate();
+
+ // We handle all (s/zext i1 Op0 + s/zext i1 Op1 ==/!= 0/1/2) here.
+ // TODO: sext -1, sext -2
+ // sext i1 X + sext i1 Y == -1 --> xor i1 X, Y
+ // https://alive2.llvm.org/ce/z/2nSJ22
+ // sext i1 X + sext i1 Y == -2 --> and i1 X, Y
+ // https://alive2.llvm.org/ce/z/rasQlX
+ if (Cmp.isEquality() &&
+ match(Add, m_c_Add(m_OneUse(m_ZExtOrSExt(m_Value(Op0))),
+ m_OneUse(m_ZExtOrSExt(m_Value(Op1))))) &&
+ Op0->getType()->isIntOrIntVectorTy(1) &&
+ Op1->getType()->isIntOrIntVectorTy(1) &&
+ (C.isZero() || C.isOne() || (C.exactLogBase2() == 1))) {
+ Value *Cond = Builder.getFalse();
+ // Handle zext/zext additions
+ if (match(X, m_OneUse(m_ZExt(m_Value(Op0)))) &&
+ match(Y, m_OneUse(m_ZExt(m_Value(Op1))))) {
+ if (Pred == ICmpInst::ICMP_EQ) {
+ // Case 1: zext i1 Op0 + zext i1 Op1 == 0 --> !(or i1 Op0, Op1)
+ if (C.isZero())
+ Cond = Builder.CreateNot(Builder.CreateOr(Op0, Op1));
+ else if (C.isOne())
+ // Case 2: zext i1 Op0 + zext i1 Op1 == 1 --> xor i1 Op0, Op1
+ Cond = Builder.CreateXor(Op0, Op1);
+ else
+ // Case 3: zext i1 Op0 + zext i1 Op1 == 2 --> xor i1 Op0, Op1
+ Cond = Builder.CreateAnd(Op0, Op1);
+ } else {
+ // Case 1: zext i1 Op0 + zext i1 Op1 != 0 --> or i1 Op0, Op1
+ if (C.isZero())
+ Cond = Builder.CreateOr(Op0, Op1);
+ else if (C.isOne())
+ // Case 2: zext i1 Op0 + zext i1 Op1 != 1 --> !(xor i1 Op0, Op1)
+ Cond = Builder.CreateNot(Builder.CreateXor(Op0, Op1));
+ else
+ // Case 3: zext i1 Op0 + zext i1 Op1 != 2 --> !(and i1 Op0, Op1)
+ Cond = Builder.CreateNot(Builder.CreateAnd(Op0, Op1));
+ }
+ return replaceInstUsesWith(Cmp, Cond);
+ }
+
+ // Handles sext i1 Op0 + sext i1 Op1 ==/!= 0/1/2
+ if (match(X, m_OneUse(m_SExt(m_Value(Op0)))) &&
+ match(Y, m_OneUse(m_SExt(m_Value(Op1))))) {
+ if (Pred == ICmpInst::ICMP_EQ) {
+ // Case 1: sext i1 Op0 + sext i1 Op1 == 0 --> !(or i1 Op0, Op1)
+ if (C.isZero())
+ Cond = Builder.CreateNot(Builder.CreateOr(Op0, Op1));
+ // Case 2: sext i1 Op0 + sext i1 Op1 == 1 --> false
+ // Case 3: sext i1 Op0 + sext i1 Op2 == 2 --> false,
+ else
+ Cond = Builder.getFalse();
+ } else {
+ // Case 1: sext i1 Op0 + sext i1 Op1 != 0 --> or i1 Op0, Op1
+ if (C.isZero())
+ Cond = Builder.CreateOr(Op0, Op1);
+ else
+ // Case 2: sext i1 Op0 + sext i1 Op1 != 1 --> true
+ // Case 3: sext i1 Op0 + sext i1 Op2 != 2 --> true
+ Cond = Builder.getTrue();
+ }
+ return replaceInstUsesWith(Cmp, Cond);
+ }
+
+ // Sum is cummulative so swap the operations to avoid recompuations
+ if (match(X, m_OneUse(m_ZExt(m_OneUse(m_Value(Op0))))) &&
+ match(Y, m_OneUse(m_SExt(m_OneUse(m_Value(Op1)))))) {
+ std::swap(Op0, Op1);
+ std::swap(X, Y);
+ }
+ // Handles sext i1 Op0 + zext Op1 == 0/1/2
+ if (match(X, m_OneUse(m_SExt(m_Value(Op0)))) &&
+ match(Y, m_OneUse(m_ZExt(m_Value(Op1))))) {
+ if (Pred == ICmpInst::ICMP_EQ) {
+ // Case 1: sext i1 Op0 + zext i1 Op1 == 0 --> !(xor i1 Op0, Op1)
+ if (C.isZero())
+ Cond = Builder.CreateNot(Builder.CreateXor(Op0, Op1));
+ else if (C.isOne())
+ // Case 2: sext i1 Op0 + zext i1 Op1 == 1 --> (!Op0) & Op1
+ Cond = Builder.CreateAnd(Builder.CreateNot(Op0), Op1);
+ else
+ // Case 3: sext i1 Op0 + zext i1 Op1 == 2 --> false
+ Cond = Builder.getFalse();
+ } else {
+ // Case 1: sext i1 Op0 + zext i1 Op1 != 0 --> xor i1 Op0, Op1
+ if (C.isZero())
+ Cond = Builder.CreateXor(Op0, Op1);
+ else if (C.isOne())
+ // Case 2: sext i1 Op0 + zext i1 Op1 != 1 --> Op0 | (!Op1)
+ Cond = Builder.CreateOr(Op0, Builder.CreateNot(Op1));
+ else
+ // Case 3: sext i1 Op0 + zext i1 Op1 != 2 --> true
+ Cond = Builder.getTrue();
+ }
+ return replaceInstUsesWith(Cmp, Cond);
+ }
+ return nullptr;
+ }
const APInt *C2;
if (Cmp.isEquality() || !match(Y, m_APInt(C2)))
return nullptr;
// Fold icmp pred (add X, C2), C.
- Value *X = Add->getOperand(0);
Type *Ty = Add->getType();
- const CmpInst::Predicate Pred = Cmp.getPredicate();
// If the add does not wrap, we can always adjust the compare by subtracting
// the constants. Equality comparisons are handled elsewhere. SGE/SLE/UGE/ULE
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index ec8d7d14d3b51f7..fae6fb0daec9ed9 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -23,10 +23,7 @@ bb:
define i1 @cvt_icmp_1_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_eq(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]]
-; CHECK-NEXT: [[I4:%.*]] = icmp eq i32 [[I3]], 1
+; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
; CHECK-NEXT: ret i1 [[I4]]
;
bb:
@@ -40,10 +37,7 @@ bb:
define i1 @cvt_icmp_2_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_eq(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 2
+; CHECK-NEXT: [[T:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
; CHECK-NEXT: ret i1 [[T]]
;
bb:
@@ -72,11 +66,7 @@ bb:
define i1 @cvt_icmp_1_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_eq(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 1
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 false
;
bb:
%i = sext i1 %arg to i32
@@ -89,11 +79,7 @@ bb:
define i1 @cvt_icmp_2_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_eq(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 2
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 false
;
bb:
%i = sext i1 %arg to i32
@@ -136,11 +122,7 @@ bb:
define i1 @cvt_icmp_2_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_eq(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 2
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 false
;
bb:
%i = sext i1 %arg to i32
@@ -153,8 +135,8 @@ bb:
define i1 @cvt_icmp_0_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_ne(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
-; CHECK-NEXT: ret i1 [[TMP0]]
+; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
;
bb:
%i = zext i1 %arg to i32
@@ -167,10 +149,8 @@ bb:
define i1 @cvt_icmp_1_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]]
-; CHECK-NEXT: [[I4:%.*]] = icmp ne i32 [[I3]], 1
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true
; CHECK-NEXT: ret i1 [[I4]]
;
bb:
@@ -184,10 +164,8 @@ bb:
define i1 @cvt_icmp_2_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_ne(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 2
+; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true
; CHECK-NEXT: ret i1 [[T]]
;
bb:
@@ -201,8 +179,8 @@ bb:
define i1 @cvt_icmp_0_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_ne(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]]
-; CHECK-NEXT: ret i1 [[TMP0]]
+; CHECK-NEXT: [[T:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: ret i1 [[T]]
;
bb:
%i = sext i1 %arg to i32
@@ -215,11 +193,7 @@ bb:
define i1 @cvt_icmp_1_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_ne(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 1
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
bb:
%i = sext i1 %arg to i32
@@ -232,11 +206,7 @@ bb:
define i1 @cvt_icmp_2_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_ne(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 2
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
bb:
%i = sext i1 %arg to i32
@@ -278,11 +248,7 @@ bb:
define i1 @cvt_icmp_2_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_ne(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = sext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 2
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
bb:
%i = sext i1 %arg to i32
@@ -298,7 +264,7 @@ bb:
define i1 @cvt_icmp_0_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_eq(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true
; CHECK-NEXT: ret i1 [[T]]
;
@@ -328,11 +294,7 @@ bb:
define i1 @cvt_icmp_2_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_eq(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[I3]], 2
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 false
;
bb:
%i = zext i1 %arg to i32
@@ -345,7 +307,7 @@ bb:
define i1 @cvt_icmp_0_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_ne(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
; CHECK-NEXT: ret i1 [[T]]
;
bb:
@@ -374,11 +336,7 @@ bb:
define i1 @cvt_icmp_2_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_ne(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
-; CHECK-NEXT: [[I2:%.*]] = sext i1 [[ARG1:%.*]] to i32
-; CHECK-NEXT: [[I3:%.*]] = add nsw i32 [[I]], [[I2]]
-; CHECK-NEXT: [[T:%.*]] = icmp ne i32 [[I3]], 2
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
bb:
%i = zext i1 %arg to i32
@@ -444,8 +402,8 @@ bb:
define i1 @test_cvt_icmp4(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @test_cvt_icmp4(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
-; CHECK-NEXT: ret i1 [[TMP0]]
+; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
;
bb:
%i = zext i1 %arg to i32
@@ -458,8 +416,8 @@ bb:
define i1 @test_cvt_icmp5(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @test_cvt_icmp5(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
-; CHECK-NEXT: ret i1 [[TMP0]]
+; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
;
bb:
%i = zext i1 %arg to i32
@@ -506,8 +464,8 @@ bb:
define i1 @test_cvt_icmp8(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @test_cvt_icmp8(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
-; CHECK-NEXT: ret i1 [[TMP0]]
+; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
;
bb:
%i = zext i1 %arg to i32
@@ -569,8 +527,8 @@ bb:
define i1 @test_cvt_icmp12(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @test_cvt_icmp12(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
-; CHECK-NEXT: ret i1 [[TMP0]]
+; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: ret i1 [[I4]]
;
bb:
%i = sext i1 %arg to i32
@@ -698,7 +656,7 @@ bb:
define i1 @test_cvt_icmp20(i1 %arg, i1 %arg1) {
; CHECK-LABEL: @test_cvt_icmp20(
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
; CHECK-NEXT: ret i1 [[I4]]
;
bb:
More information about the llvm-commits
mailing list