[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