[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