[llvm] [AMDGPU] Add and_or tests for literals shared across ThreeOp pairs (NFC) (PR #224198)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 16 23:07:15 PDT 2026
https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/224198
Split the shared GFX10 prefix into GFX10PLUS, GFX10 and GFX11, since gfx10 and gfx11 diverge on some of these
Prerequisite for https://github.com/llvm/llvm-project/pull/224049
>From 4e8a253f9ac69e545ef93999ca4d4396eaefddb5 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Thu, 17 Sep 2026 08:03:44 +0200
Subject: [PATCH] [AMDGPU] Add and_or tests for literals shared across ThreeOp
pairs (NFC)
Split the shared GFX10 prefix into GFX10PLUS, GFX10 and GFX11, since gfx10 and gfx11 diverge on some of these
---
llvm/test/CodeGen/AMDGPU/and_or.ll | 380 +++++++++++++++++++++++------
1 file changed, 304 insertions(+), 76 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/and_or.ll b/llvm/test/CodeGen/AMDGPU/and_or.ll
index 369676fbb3ed0..373e2fffcaad1 100644
--- a/llvm/test/CodeGen/AMDGPU/and_or.ll
+++ b/llvm/test/CodeGen/AMDGPU/and_or.ll
@@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
;RUN: llc < %s -mtriple=amdgpu8.03-amd-mesa3d | FileCheck -check-prefix=VI %s
;RUN: llc < %s -mtriple=amdgpu9.00-amd-mesa3d | FileCheck -check-prefix=GFX9 %s
-;RUN: llc < %s -mtriple=amdgpu10.10-amd-mesa3d | FileCheck -check-prefix=GFX10 %s
-;RUN: llc < %s -mtriple=amdgpu11.00-amd-mesa3d -amdgpu-enable-delay-alu=0 | FileCheck -check-prefix=GFX10 %s
+;RUN: llc < %s -mtriple=amdgpu10.10-amd-mesa3d | FileCheck -check-prefixes=GFX10PLUS,GFX10 %s
+;RUN: llc < %s -mtriple=amdgpu11.00-amd-mesa3d -amdgpu-enable-delay-alu=0 | FileCheck -check-prefixes=GFX10PLUS,GFX11 %s
; ===================================================================================
; V_AND_OR_B32
@@ -20,10 +20,10 @@ define amdgpu_ps float @and_or(i32 %a, i32 %b, i32 %c) {
; GFX9-NEXT: v_and_or_b32 v0, v0, v1, v2
; GFX9-NEXT: ; return to shader part epilog
;
-; GFX10-LABEL: and_or:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: v_and_or_b32 v0, v0, v1, v2
-; GFX10-NEXT: ; return to shader part epilog
+; GFX10PLUS-LABEL: and_or:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, v1, v2
+; GFX10PLUS-NEXT: ; return to shader part epilog
%x = and i32 %a, %b
%result = or i32 %x, %c
%bc = bitcast i32 %result to float
@@ -44,10 +44,10 @@ define amdgpu_ps float @and_or_vgpr_b(i32 inreg %a, i32 %b, i32 inreg %c) {
; GFX9-NEXT: v_or_b32_e32 v0, s3, v0
; GFX9-NEXT: ; return to shader part epilog
;
-; GFX10-LABEL: and_or_vgpr_b:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: v_and_or_b32 v0, s2, v0, s3
-; GFX10-NEXT: ; return to shader part epilog
+; GFX10PLUS-LABEL: and_or_vgpr_b:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: v_and_or_b32 v0, s2, v0, s3
+; GFX10PLUS-NEXT: ; return to shader part epilog
%x = and i32 %a, %b
%result = or i32 %x, %c
%bc = bitcast i32 %result to float
@@ -66,10 +66,10 @@ define amdgpu_ps float @and_or_vgpr_ab(i32 %a, i32 %b, i32 inreg %c) {
; GFX9-NEXT: v_and_or_b32 v0, v0, v1, s2
; GFX9-NEXT: ; return to shader part epilog
;
-; GFX10-LABEL: and_or_vgpr_ab:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: v_and_or_b32 v0, v0, v1, s2
-; GFX10-NEXT: ; return to shader part epilog
+; GFX10PLUS-LABEL: and_or_vgpr_ab:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, v1, s2
+; GFX10PLUS-NEXT: ; return to shader part epilog
%x = and i32 %a, %b
%result = or i32 %x, %c
%bc = bitcast i32 %result to float
@@ -88,10 +88,10 @@ define amdgpu_ps float @and_or_vgpr_const(i32 %a, i32 %b) {
; GFX9-NEXT: v_and_or_b32 v0, v0, 4, v1
; GFX9-NEXT: ; return to shader part epilog
;
-; GFX10-LABEL: and_or_vgpr_const:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: v_and_or_b32 v0, v0, 4, v1
-; GFX10-NEXT: ; return to shader part epilog
+; GFX10PLUS-LABEL: and_or_vgpr_const:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, 4, v1
+; GFX10PLUS-NEXT: ; return to shader part epilog
%x = and i32 4, %a
%result = or i32 %x, %b
%bc = bitcast i32 %result to float
@@ -111,10 +111,10 @@ define amdgpu_ps float @and_or_vgpr_const_inline_const(i32 %a) {
; GFX9-NEXT: v_and_or_b32 v0, v0, 20, v1
; GFX9-NEXT: ; return to shader part epilog
;
-; GFX10-LABEL: and_or_vgpr_const_inline_const:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: v_and_or_b32 v0, v0, 20, 0x808
-; GFX10-NEXT: ; return to shader part epilog
+; GFX10PLUS-LABEL: and_or_vgpr_const_inline_const:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, 20, 0x808
+; GFX10PLUS-NEXT: ; return to shader part epilog
%x = and i32 20, %a
%result = or i32 %x, 2056
%bc = bitcast i32 %result to float
@@ -133,10 +133,10 @@ define amdgpu_ps float @and_or_vgpr_inline_const_x2(i32 %a) {
; GFX9-NEXT: v_and_or_b32 v0, v0, 4, 1
; GFX9-NEXT: ; return to shader part epilog
;
-; GFX10-LABEL: and_or_vgpr_inline_const_x2:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: v_and_or_b32 v0, v0, 4, 1
-; GFX10-NEXT: ; return to shader part epilog
+; GFX10PLUS-LABEL: and_or_vgpr_inline_const_x2:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, 4, 1
+; GFX10PLUS-NEXT: ; return to shader part epilog
%x = and i32 4, %a
%result = or i32 %x, 1
%bc = bitcast i32 %result to float
@@ -160,12 +160,12 @@ define <2 x i32> @v_and_or_v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
; GFX9-NEXT: v_and_or_b32 v0, v0, v2, v4
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
-; GFX10-LABEL: v_and_or_v2i32:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_and_or_b32 v0, v0, v2, v4
-; GFX10-NEXT: v_and_or_b32 v1, v1, v3, v5
-; GFX10-NEXT: s_setpc_b64 s[30:31]
+; GFX10PLUS-LABEL: v_and_or_v2i32:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, v2, v4
+; GFX10PLUS-NEXT: v_and_or_b32 v1, v1, v3, v5
+; GFX10PLUS-NEXT: s_setpc_b64 s[30:31]
%x = and <2 x i32> %a, %b
%result = or <2 x i32> %x, %c
ret <2 x i32> %result
@@ -194,9 +194,16 @@ define <2 x i32> @v_and_or_v2i32_b(<2 x i32> inreg %a, <2 x i32> %b, <2 x i32> i
; GFX10-LABEL: v_and_or_v2i32_b:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-DAG: v_and_or_b32 v0, s{{[0-9]+}}, v0, s{{[0-9]+}}
-; GFX10-DAG: v_and_or_b32 v1, s{{[0-9]+}}, v1, s{{[0-9]+}}
+; GFX10-NEXT: v_and_or_b32 v0, s16, v0, s18
+; GFX10-NEXT: v_and_or_b32 v1, s17, v1, s19
; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_and_or_v2i32_b:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_and_or_b32 v0, s0, v0, s2
+; GFX11-NEXT: v_and_or_b32 v1, s1, v1, s3
+; GFX11-NEXT: s_setpc_b64 s[30:31]
%x = and <2 x i32> %a, %b
%result = or <2 x i32> %x, %c
ret <2 x i32> %result
@@ -222,9 +229,16 @@ define <2 x i32> @v_and_or_v2i32_ab(<2 x i32> %a, <2 x i32> %b, <2 x i32> inreg
; GFX10-LABEL: v_and_or_v2i32_ab:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-DAG: v_and_or_b32 v1, v1, v3, {{s[0-9]+}}
-; GFX10-DAG: v_and_or_b32 v0, v0, v2, {{s[0-9]+}}
+; GFX10-NEXT: v_and_or_b32 v0, v0, v2, s16
+; GFX10-NEXT: v_and_or_b32 v1, v1, v3, s17
; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_and_or_v2i32_ab:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_and_or_b32 v0, v0, v2, s0
+; GFX11-NEXT: v_and_or_b32 v1, v1, v3, s1
+; GFX11-NEXT: s_setpc_b64 s[30:31]
%x = and <2 x i32> %a, %b
%result = or <2 x i32> %x, %c
ret <2 x i32> %result
@@ -247,12 +261,12 @@ define <2 x i32> @v_and_or_v2i32_const(<2 x i32> %a, <2 x i32> %b) {
; GFX9-NEXT: v_and_or_b32 v0, v0, 4, v2
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
-; GFX10-LABEL: v_and_or_v2i32_const:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_and_or_b32 v0, v0, 4, v2
-; GFX10-NEXT: v_and_or_b32 v1, v1, 16, v3
-; GFX10-NEXT: s_setpc_b64 s[30:31]
+; GFX10PLUS-LABEL: v_and_or_v2i32_const:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, 4, v2
+; GFX10PLUS-NEXT: v_and_or_b32 v1, v1, 16, v3
+; GFX10PLUS-NEXT: s_setpc_b64 s[30:31]
%x = and <2 x i32> %a, <i32 4, i32 16>
%result = or <2 x i32> %x, %b
ret <2 x i32> %result
@@ -277,12 +291,12 @@ define <2 x i32> @v_and_or_v2i32_inline_const(<2 x i32> %a, <2 x i32> %b) {
; GFX9-NEXT: v_and_or_b32 v0, v0, s4, v2
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
-; GFX10-LABEL: v_and_or_v2i32_inline_const:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_and_or_b32 v0, 0x808, v0, v2
-; GFX10-NEXT: v_and_or_b32 v1, 0x809, v1, v3
-; GFX10-NEXT: s_setpc_b64 s[30:31]
+; GFX10PLUS-LABEL: v_and_or_v2i32_inline_const:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10PLUS-NEXT: v_and_or_b32 v0, 0x808, v0, v2
+; GFX10PLUS-NEXT: v_and_or_b32 v1, 0x809, v1, v3
+; GFX10PLUS-NEXT: s_setpc_b64 s[30:31]
%x = and <2 x i32> %a, <i32 2056, i32 2057>
%result = or <2 x i32> %x, %b
ret <2 x i32> %result
@@ -307,12 +321,12 @@ define <2 x i32> @v_and_or_v2i32_inline_const_x2(<2 x i32> %a) {
; GFX9-NEXT: v_or_b32_e32 v0, 4, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
-; GFX10-LABEL: v_and_or_v2i32_inline_const_x2:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_and_or_b32 v0, 0x808, v0, 4
-; GFX10-NEXT: v_and_or_b32 v1, 0x809, v1, 16
-; GFX10-NEXT: s_setpc_b64 s[30:31]
+; GFX10PLUS-LABEL: v_and_or_v2i32_inline_const_x2:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10PLUS-NEXT: v_and_or_b32 v0, 0x808, v0, 4
+; GFX10PLUS-NEXT: v_and_or_b32 v1, 0x809, v1, 16
+; GFX10PLUS-NEXT: s_setpc_b64 s[30:31]
%x = and <2 x i32> %a, <i32 2056, i32 2057>
%result = or <2 x i32> %x, <i32 4, i32 16>
ret <2 x i32> %result
@@ -340,9 +354,18 @@ define <2 x i32> @v_and_or_v2i32_inline_const_x3(<2 x i32> %a) {
; GFX10-LABEL: v_and_or_v2i32_inline_const_x3:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: s_movk_i32 [[SR:s[0-9]+]], 0x808
-; GFX10-DAG: v_and_or_b32 v0, v0, [[SR]], 0x81
-; GFX10-DAG: v_and_or_b32 v1, 0x809, v1, 16
+; GFX10-NEXT: s_movk_i32 s4, 0x808
+; GFX10-NEXT: v_and_or_b32 v1, 0x809, v1, 16
+; GFX10-NEXT: v_and_or_b32 v0, v0, s4, 0x81
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_and_or_v2i32_inline_const_x3:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: s_movk_i32 s0, 0x808
+; GFX11-NEXT: v_and_or_b32 v1, 0x809, v1, 16
+; GFX11-NEXT: v_and_or_b32 v0, v0, s0, 0x81
+; GFX11-NEXT: s_setpc_b64 s[30:31]
%x = and <2 x i32> %a, <i32 2056, i32 2057>
%result = or <2 x i32> %x, <i32 129, i32 16>
ret <2 x i32> %result
@@ -370,11 +393,21 @@ define <2 x i32> @v_and_or_v2i32_inline_const_x4(<2 x i32> %a) {
; GFX10-LABEL: v_and_or_v2i32_inline_const_x4:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-DAG: s_movk_i32 [[SR0:s[0-9]+]], 0x808
-; GFX10-DAG: s_movk_i32 [[SR1:s[0-9]+]], 0x809
+; GFX10-NEXT: s_movk_i32 s4, 0x808
+; GFX10-NEXT: s_movk_i32 s5, 0x809
+; GFX10-NEXT: v_and_or_b32 v0, v0, s4, 0x81
+; GFX10-NEXT: v_and_or_b32 v1, v1, s5, 0x101
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_and_or_v2i32_inline_const_x4:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: s_movk_i32 s0, 0x808
+; GFX11-NEXT: s_movk_i32 s1, 0x809
+; GFX11-NEXT: v_and_or_b32 v0, v0, s0, 0x81
+; GFX11-NEXT: v_and_or_b32 v1, v1, s1, 0x101
+; GFX11-NEXT: s_setpc_b64 s[30:31]
; GFX10-CHECK-NOT: {{.}}
-; GFX10-DAG: v_and_or_b32 v0, v0, [[SR0]], 0x81
-; GFX10-DAG: v_and_or_b32 v1, v1, [[SR1]], 0x101
%x = and <2 x i32> %a, <i32 2056, i32 2057>
%result = or <2 x i32> %x, <i32 129, i32 257>
ret <2 x i32> %result
@@ -403,16 +436,16 @@ define <2 x i32> @v_and_or_v2i32_multi_use(<2 x i32> %a, <2 x i32> %b, <2 x i32>
; GFX9-NEXT: v_add_u32_e32 v1, v1, v2
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
-; GFX10-LABEL: v_and_or_v2i32_multi_use:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_and_b32_e32 v0, v0, v2
-; GFX10-NEXT: v_and_b32_e32 v1, v1, v3
-; GFX10-NEXT: v_or_b32_e32 v2, v0, v4
-; GFX10-NEXT: v_or_b32_e32 v3, v1, v5
-; GFX10-NEXT: v_add_nc_u32_e32 v0, v0, v2
-; GFX10-NEXT: v_add_nc_u32_e32 v1, v1, v3
-; GFX10-NEXT: s_setpc_b64 s[30:31]
+; GFX10PLUS-LABEL: v_and_or_v2i32_multi_use:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10PLUS-NEXT: v_and_b32_e32 v0, v0, v2
+; GFX10PLUS-NEXT: v_and_b32_e32 v1, v1, v3
+; GFX10PLUS-NEXT: v_or_b32_e32 v2, v0, v4
+; GFX10PLUS-NEXT: v_or_b32_e32 v3, v1, v5
+; GFX10PLUS-NEXT: v_add_nc_u32_e32 v0, v0, v2
+; GFX10PLUS-NEXT: v_add_nc_u32_e32 v1, v1, v3
+; GFX10PLUS-NEXT: s_setpc_b64 s[30:31]
%x = and <2 x i32> %a, %b
%y = or <2 x i32> %x, %c
%result = add <2 x i32> %x, %y
@@ -432,12 +465,207 @@ define amdgpu_ps <2 x i32> @s_and_or_v2i32(<2 x i32> inreg %a, <2 x i32> inreg %
; GFX9-NEXT: s_or_b64 s[0:1], s[0:1], s[6:7]
; GFX9-NEXT: ; return to shader part epilog
;
-; GFX10-LABEL: s_and_or_v2i32:
-; GFX10: ; %bb.0:
-; GFX10-NEXT: s_and_b64 s[0:1], s[2:3], s[4:5]
-; GFX10-NEXT: s_or_b64 s[0:1], s[0:1], s[6:7]
-; GFX10-NEXT: ; return to shader part epilog
+; GFX10PLUS-LABEL: s_and_or_v2i32:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_and_b64 s[0:1], s[2:3], s[4:5]
+; GFX10PLUS-NEXT: s_or_b64 s[0:1], s[0:1], s[6:7]
+; GFX10PLUS-NEXT: ; return to shader part epilog
%x = and <2 x i32> %a, %b
%result = or <2 x i32> %x, %c
ret <2 x i32> %result
}
+
+define amdgpu_ps <3 x float> @and_or_shared_literals(<3 x i32> %a) {
+; VI-LABEL: and_or_shared_literals:
+; VI: ; %bb.0:
+; VI-NEXT: v_and_b32_e32 v2, 0xf000f, v2
+; VI-NEXT: v_and_b32_e32 v1, 0xf000f, v1
+; VI-NEXT: v_and_b32_e32 v0, 0xf000f, v0
+; VI-NEXT: v_or_b32_e32 v0, 0x64006400, v0
+; VI-NEXT: v_or_b32_e32 v1, 0x64006400, v1
+; VI-NEXT: v_or_b32_e32 v2, 0x64006400, v2
+; VI-NEXT: ; return to shader part epilog
+;
+; GFX9-LABEL: and_or_shared_literals:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: v_and_b32_e32 v2, 0xf000f, v2
+; GFX9-NEXT: v_and_b32_e32 v1, 0xf000f, v1
+; GFX9-NEXT: v_and_b32_e32 v0, 0xf000f, v0
+; GFX9-NEXT: v_or_b32_e32 v0, 0x64006400, v0
+; GFX9-NEXT: v_or_b32_e32 v1, 0x64006400, v1
+; GFX9-NEXT: v_or_b32_e32 v2, 0x64006400, v2
+; GFX9-NEXT: ; return to shader part epilog
+;
+; GFX10PLUS-LABEL: and_or_shared_literals:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_mov_b32 s0, 0xf000f
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, s0, 0x64006400
+; GFX10PLUS-NEXT: v_and_or_b32 v1, v1, s0, 0x64006400
+; GFX10PLUS-NEXT: v_and_or_b32 v2, v2, s0, 0x64006400
+; GFX10PLUS-NEXT: ; return to shader part epilog
+ %x = and <3 x i32> %a, splat (i32 983055)
+ %r = or <3 x i32> %x, splat (i32 1677747200)
+ %f = bitcast <3 x i32> %r to <3 x float>
+ ret <3 x float> %f
+}
+
+define amdgpu_ps <2 x float> @and_or_shared_literals_break_even(<2 x i32> %a) {
+; VI-LABEL: and_or_shared_literals_break_even:
+; VI: ; %bb.0:
+; VI-NEXT: v_and_b32_e32 v1, 0xf000f, v1
+; VI-NEXT: v_and_b32_e32 v0, 0xf000f, v0
+; VI-NEXT: v_or_b32_e32 v1, 0x64006400, v1
+; VI-NEXT: v_or_b32_e32 v0, 0x64006400, v0
+; VI-NEXT: ; return to shader part epilog
+;
+; GFX9-LABEL: and_or_shared_literals_break_even:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: v_and_b32_e32 v1, 0xf000f, v1
+; GFX9-NEXT: v_and_b32_e32 v0, 0xf000f, v0
+; GFX9-NEXT: v_or_b32_e32 v1, 0x64006400, v1
+; GFX9-NEXT: v_or_b32_e32 v0, 0x64006400, v0
+; GFX9-NEXT: ; return to shader part epilog
+;
+; GFX10PLUS-LABEL: and_or_shared_literals_break_even:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_mov_b32 s0, 0xf000f
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, s0, 0x64006400
+; GFX10PLUS-NEXT: v_and_or_b32 v1, v1, s0, 0x64006400
+; GFX10PLUS-NEXT: ; return to shader part epilog
+ %x = and <2 x i32> %a, splat (i32 983055)
+ %r = or <2 x i32> %x, splat (i32 1677747200)
+ %f = bitcast <2 x i32> %r to <2 x float>
+ ret <2 x float> %f
+}
+
+; Two v2i32 fragments, two instructions each, over the same pair of literals.
+define amdgpu_ps <4 x float> @and_or_shared_literals_v2i32(<2 x i32> %a, <2 x i32> %b) {
+; VI-LABEL: and_or_shared_literals_v2i32:
+; VI: ; %bb.0:
+; VI-NEXT: v_and_b32_e32 v1, 0xf000f, v1
+; VI-NEXT: v_and_b32_e32 v0, 0xf000f, v0
+; VI-NEXT: v_and_b32_e32 v3, 0xf000f, v3
+; VI-NEXT: v_and_b32_e32 v2, 0xf000f, v2
+; VI-NEXT: v_or_b32_e32 v1, 0x64006400, v1
+; VI-NEXT: v_or_b32_e32 v0, 0x64006400, v0
+; VI-NEXT: v_or_b32_e32 v3, 0x64006400, v3
+; VI-NEXT: v_or_b32_e32 v2, 0x64006400, v2
+; VI-NEXT: ; return to shader part epilog
+;
+; GFX9-LABEL: and_or_shared_literals_v2i32:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: v_and_b32_e32 v1, 0xf000f, v1
+; GFX9-NEXT: v_and_b32_e32 v0, 0xf000f, v0
+; GFX9-NEXT: v_and_b32_e32 v3, 0xf000f, v3
+; GFX9-NEXT: v_and_b32_e32 v2, 0xf000f, v2
+; GFX9-NEXT: v_or_b32_e32 v1, 0x64006400, v1
+; GFX9-NEXT: v_or_b32_e32 v0, 0x64006400, v0
+; GFX9-NEXT: v_or_b32_e32 v3, 0x64006400, v3
+; GFX9-NEXT: v_or_b32_e32 v2, 0x64006400, v2
+; GFX9-NEXT: ; return to shader part epilog
+;
+; GFX10PLUS-LABEL: and_or_shared_literals_v2i32:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_mov_b32 s0, 0xf000f
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, s0, 0x64006400
+; GFX10PLUS-NEXT: v_and_or_b32 v1, v1, s0, 0x64006400
+; GFX10PLUS-NEXT: v_and_or_b32 v2, v2, s0, 0x64006400
+; GFX10PLUS-NEXT: v_and_or_b32 v3, v3, s0, 0x64006400
+; GFX10PLUS-NEXT: ; return to shader part epilog
+ %x = and <2 x i32> %a, splat (i32 983055)
+ %r = or <2 x i32> %x, splat (i32 1677747200)
+ %x2 = and <2 x i32> %b, splat (i32 983055)
+ %r2 = or <2 x i32> %x2, splat (i32 1677747200)
+ %j = shufflevector <2 x i32> %r, <2 x i32> %r2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %f = bitcast <4 x i32> %j to <4 x float>
+ ret <4 x float> %f
+}
+
+; The same literals also feed plain adds, which take them in a free slot.
+define amdgpu_ps <5 x float> @and_or_literal_used_by_nonfused(i32 %a, <4 x i32> %b) {
+; VI-LABEL: and_or_literal_used_by_nonfused:
+; VI: ; %bb.0:
+; VI-NEXT: v_and_b32_e32 v0, 0xf000f, v0
+; VI-NEXT: v_or_b32_e32 v0, 0x64006400, v0
+; VI-NEXT: v_add_u32_e32 v1, vcc, 0xf000f, v1
+; VI-NEXT: v_add_u32_e32 v2, vcc, 0xf000f, v2
+; VI-NEXT: v_add_u32_e32 v3, vcc, 0x64006400, v3
+; VI-NEXT: v_add_u32_e32 v4, vcc, 0x64006400, v4
+; VI-NEXT: ; return to shader part epilog
+;
+; GFX9-LABEL: and_or_literal_used_by_nonfused:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: v_and_b32_e32 v0, 0xf000f, v0
+; GFX9-NEXT: v_or_b32_e32 v0, 0x64006400, v0
+; GFX9-NEXT: v_add_u32_e32 v1, 0xf000f, v1
+; GFX9-NEXT: v_add_u32_e32 v2, 0xf000f, v2
+; GFX9-NEXT: v_add_u32_e32 v3, 0x64006400, v3
+; GFX9-NEXT: v_add_u32_e32 v4, 0x64006400, v4
+; GFX9-NEXT: ; return to shader part epilog
+;
+; GFX10PLUS-LABEL: and_or_literal_used_by_nonfused:
+; GFX10PLUS: ; %bb.0:
+; GFX10PLUS-NEXT: s_mov_b32 s0, 0xf000f
+; GFX10PLUS-NEXT: v_add_nc_u32_e32 v1, 0xf000f, v1
+; GFX10PLUS-NEXT: v_and_or_b32 v0, v0, s0, 0x64006400
+; GFX10PLUS-NEXT: v_add_nc_u32_e32 v2, 0xf000f, v2
+; GFX10PLUS-NEXT: v_add_nc_u32_e32 v3, 0x64006400, v3
+; GFX10PLUS-NEXT: v_add_nc_u32_e32 v4, 0x64006400, v4
+; GFX10PLUS-NEXT: ; return to shader part epilog
+ %x = and i32 %a, 983055
+ %r = or i32 %x, 1677747200
+ %u = add <4 x i32> %b, <i32 983055, i32 983055, i32 1677747200, i32 1677747200>
+ %s = shufflevector <4 x i32> %u, <4 x i32> poison, <5 x i32> <i32 poison, i32 0, i32 1, i32 2, i32 3>
+ %v = insertelement <5 x i32> %s, i32 %r, i32 0
+ %f = bitcast <5 x i32> %v to <5 x float>
+ ret <5 x float> %f
+}
+
+; A multiply and add pair, which fuses into the quarter rate 64-bit MAD.
+define amdgpu_ps <3 x float> @mul_add_shared_literals(<3 x i32> %a) {
+; VI-LABEL: mul_add_shared_literals:
+; VI: ; %bb.0:
+; VI-NEXT: s_mov_b32 s0, 0xf000f
+; VI-NEXT: v_mul_lo_u32 v0, v0, s0
+; VI-NEXT: v_mul_lo_u32 v2, v2, s0
+; VI-NEXT: v_mul_lo_u32 v1, v1, s0
+; VI-NEXT: v_add_u32_e32 v0, vcc, 0x64006400, v0
+; VI-NEXT: v_add_u32_e32 v1, vcc, 0x64006400, v1
+; VI-NEXT: v_add_u32_e32 v2, vcc, 0x64006400, v2
+; VI-NEXT: ; return to shader part epilog
+;
+; GFX9-LABEL: mul_add_shared_literals:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_mov_b32 s0, 0xf000f
+; GFX9-NEXT: v_mul_lo_u32 v0, v0, s0
+; GFX9-NEXT: v_mul_lo_u32 v1, v1, s0
+; GFX9-NEXT: v_mul_lo_u32 v2, v2, s0
+; GFX9-NEXT: v_add_u32_e32 v0, 0x64006400, v0
+; GFX9-NEXT: v_add_u32_e32 v1, 0x64006400, v1
+; GFX9-NEXT: v_add_u32_e32 v2, 0x64006400, v2
+; GFX9-NEXT: ; return to shader part epilog
+;
+; GFX10-LABEL: mul_add_shared_literals:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: v_mov_b32_e32 v3, v2
+; GFX10-NEXT: v_mov_b32_e32 v2, v1
+; GFX10-NEXT: s_mov_b32 s0, 0xf000f
+; GFX10-NEXT: v_mad_u64_u32 v[0:1], s1, v0, s0, 0x64006400
+; GFX10-NEXT: v_mad_u64_u32 v[1:2], s1, v2, s0, 0x64006400
+; GFX10-NEXT: v_mad_u64_u32 v[2:3], s0, v3, s0, 0x64006400
+; GFX10-NEXT: ; return to shader part epilog
+;
+; GFX11-LABEL: mul_add_shared_literals:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: v_dual_mov_b32 v4, v2 :: v_dual_mov_b32 v3, v1
+; GFX11-NEXT: v_mov_b32_e32 v2, v0
+; GFX11-NEXT: s_mov_b32 s0, 0xf000f
+; GFX11-NEXT: v_mad_u64_u32 v[0:1], null, v2, s0, 0x64006400
+; GFX11-NEXT: v_mad_u64_u32 v[1:2], null, v3, s0, 0x64006400
+; GFX11-NEXT: v_mad_u64_u32 v[2:3], null, v4, s0, 0x64006400
+; GFX11-NEXT: ; return to shader part epilog
+ %x = mul <3 x i32> %a, splat (i32 983055)
+ %r = add <3 x i32> %x, splat (i32 1677747200)
+ %f = bitcast <3 x i32> %r to <3 x float>
+ ret <3 x float> %f
+}
More information about the llvm-commits
mailing list