================
@@ -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
----------------
uweigand wrote:
Given the assertion, it should have been possible for common code to optimize
this already to CC == 3. Would be interesting to find out why that didn't
happen (but that can be done later).
https://github.com/llvm/llvm-project/pull/125970
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits