Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GlobalISel] Make the Combiner insert G_FREEZE when converting G_SELECT to binary operations. #82733

Merged
merged 1 commit into from
Feb 26, 2024

Conversation

resistor
Copy link
Collaborator

This is needed because the binary operators (G_OR and G_AND) do
not have the poison-suppressing semantics of G_SELECT.

Fixes #72475

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 23, 2024

@llvm/pr-subscribers-llvm-globalisel

@llvm/pr-subscribers-backend-aarch64

Author: Owen Anderson (resistor)

Changes

This is needed because the binary operators (G_OR and G_AND) do
not have the poison-suppressing semantics of G_SELECT.

Fixes #72475


Full diff: https://github.com/llvm/llvm-project/pull/82733.diff

3 Files Affected:

  • (modified) llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp (+12-4)
  • (modified) llvm/test/CodeGen/AArch64/cmp-chains.ll (+10-5)
  • (added) llvm/test/CodeGen/AArch64/select-to-binop-freeze.mir (+358)
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index e8a5c6fedc395a..acb2e2aef9678c 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -6511,7 +6511,9 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
       B.setInstrAndDebugLoc(*Select);
       Register Ext = MRI.createGenericVirtualRegister(TrueTy);
       B.buildZExtOrTrunc(Ext, Cond);
-      B.buildOr(DstReg, Ext, False, Flags);
+      Register FreezeFalse = MRI.createGenericVirtualRegister(TrueTy);
+      B.buildFreeze(FreezeFalse, False);
+      B.buildOr(DstReg, Ext, FreezeFalse, Flags);
     };
     return true;
   }
@@ -6523,7 +6525,9 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
       B.setInstrAndDebugLoc(*Select);
       Register Ext = MRI.createGenericVirtualRegister(TrueTy);
       B.buildZExtOrTrunc(Ext, Cond);
-      B.buildAnd(DstReg, Ext, True);
+      Register FreezeTrue = MRI.createGenericVirtualRegister(TrueTy);
+      B.buildFreeze(FreezeTrue, True);
+      B.buildAnd(DstReg, Ext, FreezeTrue);
     };
     return true;
   }
@@ -6538,7 +6542,9 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
       // Then an ext to match the destination register.
       Register Ext = MRI.createGenericVirtualRegister(TrueTy);
       B.buildZExtOrTrunc(Ext, Inner);
-      B.buildOr(DstReg, Ext, True, Flags);
+      Register FreezeTrue = MRI.createGenericVirtualRegister(TrueTy);
+      B.buildFreeze(FreezeTrue, True);
+      B.buildOr(DstReg, Ext, FreezeTrue, Flags);
     };
     return true;
   }
@@ -6553,7 +6559,9 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
       // Then an ext to match the destination register.
       Register Ext = MRI.createGenericVirtualRegister(TrueTy);
       B.buildZExtOrTrunc(Ext, Inner);
-      B.buildAnd(DstReg, Ext, False);
+      Register FreezeFalse = MRI.createGenericVirtualRegister(TrueTy);
+      B.buildFreeze(FreezeFalse, False);
+      B.buildAnd(DstReg, Ext, FreezeFalse);
     };
     return true;
   }
diff --git a/llvm/test/CodeGen/AArch64/cmp-chains.ll b/llvm/test/CodeGen/AArch64/cmp-chains.ll
index c4ad84d9fa25ba..1d9f39e5185939 100644
--- a/llvm/test/CodeGen/AArch64/cmp-chains.ll
+++ b/llvm/test/CodeGen/AArch64/cmp-chains.ll
@@ -109,7 +109,8 @@ define i32 @cmp_or2(i32 %0, i32 %1, i32 %2, i32 %3) {
 ; GISEL-NEXT:    cset w8, lo
 ; GISEL-NEXT:    cmp w2, w3
 ; GISEL-NEXT:    cset w9, ne
-; GISEL-NEXT:    orr w0, w8, w9
+; GISEL-NEXT:    orr w8, w8, w9
+; GISEL-NEXT:    and w0, w8, #0x1
 ; GISEL-NEXT:    ret
   %5 = icmp ult i32 %0, %1
   %6 = icmp ne i32 %2, %3
@@ -137,7 +138,8 @@ define i32 @cmp_or3(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5) {
 ; GISEL-NEXT:    cmp w4, w5
 ; GISEL-NEXT:    orr w8, w8, w9
 ; GISEL-NEXT:    cset w9, ne
-; GISEL-NEXT:    orr w0, w8, w9
+; GISEL-NEXT:    orr w8, w8, w9
+; GISEL-NEXT:    and w0, w8, #0x1
 ; GISEL-NEXT:    ret
   %7 = icmp ult i32 %0, %1
   %8 = icmp ugt i32 %2, %3
@@ -171,7 +173,8 @@ define i32 @cmp_or4(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32
 ; GISEL-NEXT:    orr w8, w8, w9
 ; GISEL-NEXT:    cset w11, eq
 ; GISEL-NEXT:    orr w9, w10, w11
-; GISEL-NEXT:    orr w0, w8, w9
+; GISEL-NEXT:    orr w8, w8, w9
+; GISEL-NEXT:    and w0, w8, #0x1
 ; GISEL-NEXT:    ret
   %9 = icmp ult i32 %0, %1
   %10 = icmp ugt i32 %2, %3
@@ -199,7 +202,8 @@ define i32 @true_or2(i32 %0, i32 %1) {
 ; GISEL-NEXT:    cset w8, ne
 ; GISEL-NEXT:    cmp w1, #0
 ; GISEL-NEXT:    cset w9, ne
-; GISEL-NEXT:    orr w0, w8, w9
+; GISEL-NEXT:    orr w8, w8, w9
+; GISEL-NEXT:    and w0, w8, #0x1
 ; GISEL-NEXT:    ret
   %3 = icmp ne i32 %0, 0
   %4 = icmp ne i32 %1, 0
@@ -227,7 +231,8 @@ define i32 @true_or3(i32 %0, i32 %1, i32 %2) {
 ; GISEL-NEXT:    cmp w2, #0
 ; GISEL-NEXT:    orr w8, w8, w9
 ; GISEL-NEXT:    cset w9, ne
-; GISEL-NEXT:    orr w0, w8, w9
+; GISEL-NEXT:    orr w8, w8, w9
+; GISEL-NEXT:    and w0, w8, #0x1
 ; GISEL-NEXT:    ret
   %4 = icmp ne i32 %0, 0
   %5 = icmp ne i32 %1, 0
diff --git a/llvm/test/CodeGen/AArch64/select-to-binop-freeze.mir b/llvm/test/CodeGen/AArch64/select-to-binop-freeze.mir
new file mode 100644
index 00000000000000..0e9e1e120a7906
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/select-to-binop-freeze.mir
@@ -0,0 +1,358 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
+# RUN: llc -mtriple=aarch64-linux-gnu -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
+
+...
+---
+name:            f1
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
+  - { id: 6, class: _ }
+  - { id: 7, class: _ }
+  - { id: 8, class: _ }
+  - { id: 9, class: _ }
+  - { id: 10, class: _ }
+liveins:
+  - { reg: '$w0' }
+  - { reg: '$w1' }
+frameInfo:
+  maxAlignment:    1
+machineFunctionInfo: {}
+body:             |
+  bb.1:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: f1
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+    ; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC]], 1
+    ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT]](s8)
+    ; CHECK-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC1]], 1
+    ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT1]](s8)
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE [[TRUNC3]]
+    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s1) = G_OR [[TRUNC2]], [[FREEZE]]
+    ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[OR]](s1)
+    ; CHECK-NEXT: $w0 = COPY [[ZEXT]](s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %4:_(s32) = COPY $w0
+    %2:_(s8) = G_TRUNC %4(s32)
+    %5:_(s32) = COPY $w1
+    %3:_(s8) = G_TRUNC %5(s32)
+    %6:_(s8) = G_ASSERT_ZEXT %2, 1
+    %0:_(s1) = G_TRUNC %6(s8)
+    %7:_(s8) = G_ASSERT_ZEXT %3, 1
+    %1:_(s1) = G_TRUNC %7(s8)
+    %8:_(s1) = G_SELECT %0(s1), %0, %1
+    %9:_(s8) = G_ZEXT %8(s1)
+    %10:_(s32) = G_ANYEXT %9(s8)
+    $w0 = COPY %10(s32)
+    RET_ReallyLR implicit $w0
+
+...
+---
+name:            f2
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
+  - { id: 6, class: _ }
+  - { id: 7, class: _ }
+  - { id: 8, class: _ }
+  - { id: 9, class: _ }
+  - { id: 10, class: _ }
+  - { id: 11, class: _ }
+liveins:
+  - { reg: '$w0' }
+  - { reg: '$w1' }
+frameInfo:
+  maxAlignment:    1
+machineFunctionInfo: {}
+body:             |
+  bb.1:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: f2
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+    ; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC]], 1
+    ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT]](s8)
+    ; CHECK-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC1]], 1
+    ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT1]](s8)
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE [[TRUNC3]]
+    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s1) = G_OR [[TRUNC2]], [[FREEZE]]
+    ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[OR]](s1)
+    ; CHECK-NEXT: $w0 = COPY [[ZEXT]](s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %4:_(s32) = COPY $w0
+    %2:_(s8) = G_TRUNC %4(s32)
+    %5:_(s32) = COPY $w1
+    %3:_(s8) = G_TRUNC %5(s32)
+    %6:_(s8) = G_ASSERT_ZEXT %2, 1
+    %0:_(s1) = G_TRUNC %6(s8)
+    %7:_(s8) = G_ASSERT_ZEXT %3, 1
+    %1:_(s1) = G_TRUNC %7(s8)
+    %9:_(s1) = G_CONSTANT i1 true
+    %8:_(s1) = G_SELECT %0(s1), %9, %1
+    %10:_(s8) = G_ZEXT %8(s1)
+    %11:_(s32) = G_ANYEXT %10(s8)
+    $w0 = COPY %11(s32)
+    RET_ReallyLR implicit $w0
+
+...
+---
+name:            f3
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
+  - { id: 6, class: _ }
+  - { id: 7, class: _ }
+  - { id: 8, class: _ }
+  - { id: 9, class: _ }
+  - { id: 10, class: _ }
+liveins:
+  - { reg: '$w0' }
+  - { reg: '$w1' }
+frameInfo:
+  maxAlignment:    1
+machineFunctionInfo: {}
+body:             |
+  bb.1:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: f3
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+    ; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC]], 1
+    ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT]](s8)
+    ; CHECK-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC1]], 1
+    ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT1]](s8)
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE [[TRUNC3]]
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[TRUNC2]], [[FREEZE]]
+    ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[AND]](s1)
+    ; CHECK-NEXT: $w0 = COPY [[ZEXT]](s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %4:_(s32) = COPY $w0
+    %2:_(s8) = G_TRUNC %4(s32)
+    %5:_(s32) = COPY $w1
+    %3:_(s8) = G_TRUNC %5(s32)
+    %6:_(s8) = G_ASSERT_ZEXT %2, 1
+    %0:_(s1) = G_TRUNC %6(s8)
+    %7:_(s8) = G_ASSERT_ZEXT %3, 1
+    %1:_(s1) = G_TRUNC %7(s8)
+    %8:_(s1) = G_SELECT %0(s1), %1, %0
+    %9:_(s8) = G_ZEXT %8(s1)
+    %10:_(s32) = G_ANYEXT %9(s8)
+    $w0 = COPY %10(s32)
+    RET_ReallyLR implicit $w0
+
+...
+---
+name:            f4
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
+  - { id: 6, class: _ }
+  - { id: 7, class: _ }
+  - { id: 8, class: _ }
+  - { id: 9, class: _ }
+  - { id: 10, class: _ }
+  - { id: 11, class: _ }
+liveins:
+  - { reg: '$w0' }
+  - { reg: '$w1' }
+frameInfo:
+  maxAlignment:    1
+machineFunctionInfo: {}
+body:             |
+  bb.1:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: f4
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+    ; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC]], 1
+    ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT]](s8)
+    ; CHECK-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC1]], 1
+    ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT1]](s8)
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE [[TRUNC3]]
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[TRUNC2]], [[FREEZE]]
+    ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[AND]](s1)
+    ; CHECK-NEXT: $w0 = COPY [[ZEXT]](s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %4:_(s32) = COPY $w0
+    %2:_(s8) = G_TRUNC %4(s32)
+    %5:_(s32) = COPY $w1
+    %3:_(s8) = G_TRUNC %5(s32)
+    %6:_(s8) = G_ASSERT_ZEXT %2, 1
+    %0:_(s1) = G_TRUNC %6(s8)
+    %7:_(s8) = G_ASSERT_ZEXT %3, 1
+    %1:_(s1) = G_TRUNC %7(s8)
+    %9:_(s1) = G_CONSTANT i1 false
+    %8:_(s1) = G_SELECT %0(s1), %1, %9
+    %10:_(s8) = G_ZEXT %8(s1)
+    %11:_(s32) = G_ANYEXT %10(s8)
+    $w0 = COPY %11(s32)
+    RET_ReallyLR implicit $w0
+
+...
+---
+name:            f5
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
+  - { id: 6, class: _ }
+  - { id: 7, class: _ }
+  - { id: 8, class: _ }
+  - { id: 9, class: _ }
+  - { id: 10, class: _ }
+  - { id: 11, class: _ }
+liveins:
+  - { reg: '$w0' }
+  - { reg: '$w1' }
+frameInfo:
+  maxAlignment:    1
+machineFunctionInfo: {}
+body:             |
+  bb.1:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: f5
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+    ; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC]], 1
+    ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT]](s8)
+    ; CHECK-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC1]], 1
+    ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT1]](s8)
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[TRUNC2]], [[C]]
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE [[TRUNC3]]
+    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s1) = G_OR [[XOR]], [[FREEZE]]
+    ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[OR]](s1)
+    ; CHECK-NEXT: $w0 = COPY [[ZEXT]](s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %4:_(s32) = COPY $w0
+    %2:_(s8) = G_TRUNC %4(s32)
+    %5:_(s32) = COPY $w1
+    %3:_(s8) = G_TRUNC %5(s32)
+    %6:_(s8) = G_ASSERT_ZEXT %2, 1
+    %0:_(s1) = G_TRUNC %6(s8)
+    %7:_(s8) = G_ASSERT_ZEXT %3, 1
+    %1:_(s1) = G_TRUNC %7(s8)
+    %9:_(s1) = G_CONSTANT i1 true
+    %8:_(s1) = G_SELECT %0(s1), %1, %9
+    %10:_(s8) = G_ZEXT %8(s1)
+    %11:_(s32) = G_ANYEXT %10(s8)
+    $w0 = COPY %11(s32)
+    RET_ReallyLR implicit $w0
+
+...
+---
+name:            f6
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
+  - { id: 6, class: _ }
+  - { id: 7, class: _ }
+  - { id: 8, class: _ }
+  - { id: 9, class: _ }
+  - { id: 10, class: _ }
+  - { id: 11, class: _ }
+liveins:
+  - { reg: '$w0' }
+  - { reg: '$w1' }
+frameInfo:
+  maxAlignment:    1
+machineFunctionInfo: {}
+body:             |
+  bb.1:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: f6
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+    ; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC]], 1
+    ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT]](s8)
+    ; CHECK-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC1]], 1
+    ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_ZEXT1]](s8)
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[TRUNC2]], [[C]]
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE [[TRUNC3]]
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[XOR]], [[FREEZE]]
+    ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[AND]](s1)
+    ; CHECK-NEXT: $w0 = COPY [[ZEXT]](s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %4:_(s32) = COPY $w0
+    %2:_(s8) = G_TRUNC %4(s32)
+    %5:_(s32) = COPY $w1
+    %3:_(s8) = G_TRUNC %5(s32)
+    %6:_(s8) = G_ASSERT_ZEXT %2, 1
+    %0:_(s1) = G_TRUNC %6(s8)
+    %7:_(s8) = G_ASSERT_ZEXT %3, 1
+    %1:_(s1) = G_TRUNC %7(s8)
+    %9:_(s1) = G_CONSTANT i1 false
+    %8:_(s1) = G_SELECT %0(s1), %9, %1
+    %10:_(s8) = G_ZEXT %8(s1)
+    %11:_(s32) = G_ANYEXT %10(s8)
+    $w0 = COPY %11(s32)
+    RET_ReallyLR implicit $w0
+
+...

G_SELECT to binary operations.

This is needed because the binary operators (G_OR and G_AND) do
not have the poison-suppressing semantics of G_SELECT.

Fixes llvm#72475
@resistor resistor merged commit ebb64d8 into llvm:main Feb 26, 2024
3 of 4 checks passed
dfszabo added a commit to dfszabo/llvm-project that referenced this pull request Feb 29, 2024
…mbines

The fix llvm#82733 introduced G_FREEZE in between of resulting instructions of some combines. This cause some inefficient code generation and loss of combine opportunities, since most of the combines does not handle G_FREEZE. A solution could be to move the G_FREEZE upper in the BB if possible, but also doing it cautiously to not introduce more G_FREEZE.

This change only add pattern for G_ICMP for now, but for most of the instruction this can be applied as well.
dfszabo added a commit to dfszabo/llvm-project that referenced this pull request Feb 29, 2024
…mbines

The fix llvm#82733 introduced G_FREEZE in between of resulting instructions of some combines. This cause some inefficient code generation and loss of combine opportunities, since most of the combines does not handle G_FREEZE. A solution could be to move the G_FREEZE upper in the BB if possible.

This change only add pattern for G_ICMP for now, but for most of the instruction this can be applied as well.
dfszabo added a commit to dfszabo/llvm-project that referenced this pull request Feb 29, 2024
…mbines

The fix llvm#82733 introduced G_FREEZE in between of resulting instructions of some combines. This cause some inefficient code generation and loss of combine opportunities, since most of the combines does not handle G_FREEZE. A solution could be to move the G_FREEZE upper in the BB if possible.

This change only add pattern for G_ICMP for now, but for most of the instruction this can be applied as well.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AArch64 miscompile of i1 arithmetic with global isel
3 participants