[clang] [llvm] Add support for flag output operand "=@cc" for SystemZ. (PR #125970)

Ulrich Weigand via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 1 04:38:18 PDT 2025


================
@@ -0,0 +1,786 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test Flag Output Operands with 14 combinations of CCMASK and optimizations.
+; This test negate of flag_output_operand_ccand, e.g
+; CC != 0 && cc != 1 && cc != 2 for AND for three different functions,
+; including two test cases from heiko.
+
+; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -O2 | FileCheck %s
+
+; Test CC != 0 && CC != 1.
+define signext range(i32 0, 43) i32 @foo_01(i32 noundef signext %x) {
+; CHECK-LABEL: foo_01:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    bnler %r14
+; CHECK-NEXT:  .LBB0_1: # %entry
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = icmp samesign ugt i32 %asmresult1, 1
+  %cond = select i1 %2, i32 42, i32 0
+  ret i32 %cond
+}
+
+declare void @llvm.assume(i1 noundef) #1
+
+; Test CC != 0 && CC != 2.
+define signext range(i32 0, 43) i32 @foo_02(i32 noundef signext %x) {
+; CHECK-LABEL: foo_02:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    bher %r14
+; CHECK-NEXT:  .LBB1_1: # %entry
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = and i32 %asmresult1, 1
+  %.not = icmp eq i32 %2, 0
+  %cond = select i1 %.not, i32 0, i32 42
+  ret i32 %cond
+}
+
+; Test CC != 0 && CC != 3.
+define signext range(i32 0, 43) i32 @foo_03(i32 noundef signext %x) {
+; CHECK-LABEL: foo_03:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    blhr %r14
+; CHECK-NEXT:  .LBB2_1: # %entry
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %cmp = icmp ne i32 %asmresult1, 0
+  %cmp2 = icmp ne i32 %asmresult1, 3
+  %2 = and i1 %cmp, %cmp2
+  %cond = select i1 %2, i32 42, i32 0
+  ret i32 %cond
+}
+
+; Test CC != 1 && CC != 2.
+define signext range(i32 0, 43) i32 @foo_12(i32 noundef signext %x) {
+; CHECK-LABEL: foo_12:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    bnlhr %r14
+; CHECK-NEXT:  .LBB3_1: # %entry
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = add nsw i32 %asmresult1, -3
+  %3 = icmp ult i32 %2, -2
+  %cond = select i1 %3, i32 42, i32 0
+  ret i32 %cond
+}
+
+; Test CC != 1 && CC != 3.
+define signext range(i32 0, 43) i32 @foo_13(i32 noundef signext %x) {
+; CHECK-LABEL: foo_13:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    bher %r14
+; CHECK-NEXT:  .LBB4_1: # %entry
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = and i32 %asmresult1, 1
+  %.not.not = icmp eq i32 %2, 0
+  %cond = select i1 %.not.not, i32 42, i32 0
+  ret i32 %cond
+}
+
+; Test CC != 2 && CC != 3.
+define signext range(i32 0, 43) i32 @foo_23(i32 noundef signext %x) {
+; CHECK-LABEL: foo_23:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    bler %r14
+; CHECK-NEXT:  .LBB5_1: # %entry
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = or disjoint i32 %asmresult1, -4
+  %3 = icmp samesign ult i32 %2, -2
+  %cond = select i1 %3, i32 42, i32 0
+  ret i32 %cond
+}
+
+; Test CC != 0 && CC != 1 && CC != 2
+define signext range(i32 0, 43) i32 @foo_012(i32 noundef signext %x) {
+; CHECK-LABEL: foo_012:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    bor %r14
+; CHECK-NEXT:  .LBB6_1: # %entry
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %or.cond = icmp samesign ugt i32 %asmresult1, 1
+  %cmp3.not = icmp eq i32 %asmresult1, 2
+  %2 = select i1 %cmp3.not, i32 0, i32 42
+  %cond = select i1 %or.cond, i32 %2, i32 0
+  ret i32 %cond
+}
+
+; Test CC != 0 && CC != 1 && CC != 3.
+define signext range(i32 0, 43) i32 @foo_013(i32 noundef signext %x) {
+; CHECK-LABEL: foo_013:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    bhr %r14
+; CHECK-NEXT:  .LBB7_1: # %entry
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %or.cond = icmp samesign ugt i32 %asmresult1, 1
+  %cmp3.not = icmp eq i32 %asmresult1, 3
+  %2 = select i1 %cmp3.not, i32 0, i32 42
+  %cond = select i1 %or.cond, i32 %2, i32 0
+  ret i32 %cond
+}
+
+; Test CC != 0 && CC != 2 && CC != 3.
+define signext range(i32 0, 43) i32 @foo_023(i32 noundef signext %x) {
+; CHECK-LABEL: foo_023:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    bnlr %r14
+; CHECK-NEXT:  .LBB8_1: # %entry
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = and i32 %asmresult1, 1
+  %or.cond.not = icmp eq i32 %2, 0
+  %cmp3.not = icmp eq i32 %asmresult1, 3
+  %3 = or i1 %cmp3.not, %or.cond.not
+  %cond = select i1 %3, i32 0, i32 42
+  ret i32 %cond
+}
+
+; Test CC != 1 && CC != 2 && CC != 3.
+define signext range(i32 0, 43) i32 @foo_123(i32 noundef signext %x) {
+; CHECK-LABEL: foo_123:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    ahi %r2, 42
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 42
+; CHECK-NEXT:    ber %r14
+; CHECK-NEXT:  .LBB9_1: # %entry
+; CHECK-NEXT:    lghi %r2, 0
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call { i32, i32 } asm "ahi $0,42\0A", "=d,={@cc},0"(i32 %x) #2
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = icmp ult i32 %asmresult1, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = add nsw i32 %asmresult1, -3
+  %or.cond = icmp ult i32 %2, -2
+  %cmp3.not = icmp eq i32 %asmresult1, 3
+  %3 = select i1 %cmp3.not, i32 0, i32 42
+  %cond = select i1 %or.cond, i32 %3, i32 0
+  ret i32 %cond
+}
+
+ at a = dso_local global i32 0, align 4
+
+; Test CC != 0 && CC != 1.
+define dso_local range(i64 5, 9) i64 @fu_01() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_01:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    bler %r14
+; CHECK-NEXT:  .LBB10_1: # %entry
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = icmp samesign ult i32 %0, 2
+  %. = select i1 %2, i64 8, i64 5
+  ret i64 %.
+}
+
+; Test CC != 0 && CC != 2.
+define dso_local range(i64 5, 9) i64 @fu_02() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_02:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    bher %r14
+; CHECK-NEXT:  .LBB11_1: # %entry
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = and i32 %0, 1
+  %tobool.not = icmp eq i32 %2, 0
+  %. = select i1 %tobool.not, i64 8, i64 5
+  ret i64 %.
+}
+
+; Test CC != 0 && CC != 3.
+define dso_local range(i64 5, 9) i64 @fu_03() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_03:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    bnlhr %r14
+; CHECK-NEXT:  .LBB12_1: # %entry
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %cmp.i = icmp eq i32 %0, 0
+  %cmp1.i = icmp eq i32 %0, 3
+  %.not = or i1 %cmp.i, %cmp1.i
+  %. = select i1 %.not, i64 8, i64 5
+  ret i64 %.
+}
+
+; Test CC != 1 && CC != 2.
+define dso_local range(i64 5, 9) i64 @fu_12() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_12:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    blhr %r14
+; CHECK-NEXT:  .LBB13_1: # %entry
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = add nsw i32 %0, -1
+  %3 = icmp ult i32 %2, 2
+  %. = select i1 %3, i64 8, i64 5
+  ret i64 %.
+}
+
+; Test CC != 1 && CC != 3.
+define dso_local range(i64 5, 9) i64 @fu_13() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_13:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    bher %r14
+; CHECK-NEXT:  .LBB14_1: # %entry
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = and i32 %0, 1
+  %tobool.not.not = icmp eq i32 %2, 0
+  %. = select i1 %tobool.not.not, i64 5, i64 8
+  ret i64 %.
+}
+
+; Test CC != 2 && CC != 3.
+define dso_local range(i64 5, 9) i64 @fu_23() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_23:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    bnler %r14
+; CHECK-NEXT:  .LBB15_1: # %entry
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = or disjoint i32 %0, -4
+  %3 = icmp samesign ugt i32 %2, -3
+  %. = select i1 %3, i64 8, i64 5
+  ret i64 %.
+}
+
+; Test CC != 0 && CC != 1 && CC != 2.
+define dso_local range(i64 5, 9) i64 @fu_012() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_012:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    bor %r14
+; CHECK-NEXT:  .LBB16_1: # %entry
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %narrow.not = icmp eq i32 %0, 3
+  %. = select i1 %narrow.not, i64 5, i64 8
+  ret i64 %.
+}
+
+; Test CC != 0 && CC != 1 && CC != 3.
+define dso_local range(i64 5, 9) i64 @fu_013() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_013:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    bnhr %r14
+; CHECK-NEXT:  .LBB17_1: # %entry
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %or.cond.i = icmp samesign ult i32 %0, 2
+  %cmp2.i = icmp eq i32 %0, 3
+  %narrow.not = or i1 %or.cond.i, %cmp2.i
+  %. = select i1 %narrow.not, i64 8, i64 5
+  ret i64 %.
+}
+
+; Test CC != 0 && CC != 2 && CC != 3.
+define dso_local range(i64 5, 9) i64 @fu_023() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_023:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    bnlr %r14
+; CHECK-NEXT:  .LBB18_1: # %entry
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = and i32 %0, 1
+  %or.cond.not.i = icmp eq i32 %2, 0
+  %cmp2.i = icmp eq i32 %0, 3
+  %narrow.not = or i1 %cmp2.i, %or.cond.not.i
+  %. = select i1 %narrow.not, i64 8, i64 5
+  ret i64 %.
+}
+
+; Test CC != 1 && CC != 2 && CC != 3.
+define dso_local range(i64 5, 9) i64 @fu_123() local_unnamed_addr #0 {
+; CHECK-LABEL: fu_123:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    lghi %r2, 5
+; CHECK-NEXT:    ber %r14
+; CHECK-NEXT:  .LBB19_1: # %entry
+; CHECK-NEXT:    lghi %r2, 8
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #2
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %narrow.not = icmp eq i32 %0, 0
+  %. = select i1 %narrow.not, i64 5, i64 8
+  ret i64 %.
+}
+
+; Test CC != 0 && CC != 1.
+define void @bar_01(){
+; CHECK-LABEL: bar_01:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    jgnle dummy at PLT
+; CHECK-NEXT:  .LBB20_1: # %if.end
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #3
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = icmp samesign ult i32 %0, 2
+  br i1 %2, label %if.end, label %if.then
+
+if.then:                                          ; preds = %entry
+  tail call void @dummy() #3
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+
+declare void @dummy() local_unnamed_addr #1
+
+; Test CC != 0 && CC != 2.
+define void @bar_02(){
+; CHECK-LABEL: bar_02:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    larl %r1, a
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    alsi 0(%r1), -1
+; CHECK-EMPTY:
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    jgnhe dummy at PLT
+; CHECK-NEXT:  .LBB21_1: # %if.end
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 asm "       alsi    $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr nonnull elementtype(i32) @a, ptr nonnull elementtype(i32) @a) #3
+  %1 = icmp ult i32 %0, 4
+  tail call void @llvm.assume(i1 %1)
+  %2 = and i32 %0, 1
+  %tobool.not = icmp eq i32 %2, 0
+  br i1 %tobool.not, label %if.end, label %if.then
+
+if.then:                                          ; preds = %entry
+  tail call void @dummy() #3
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+
+; Test CC != 0 && CC != 3.
+; TODO: DAGCombiner is not able to optimize srl/ipm/cc sequence because of
+; switch table created by simplifyBranchOnICmpChain.
----------------
uweigand wrote:

Hmm.  There was another test `fu_03` where apparently the optimizer was able to do something?  Why does that not happen here?

https://github.com/llvm/llvm-project/pull/125970


More information about the llvm-commits mailing list