|
| 1 | +; RUN: not %dxv %s 2>&1 | FileCheck %s |
| 2 | + |
| 3 | +; Negative tests for the TGSM pointer chain walk added with chained GEP / |
| 4 | +; bitcast support. The validator only walks through GEP and bitcast |
| 5 | +; operators / instructions; any other construct (phi, select, etc.) in |
| 6 | +; the middle of a chain leaves the ultimate base ambiguous and must be |
| 7 | +; rejected. Both the phi/select itself (which produces a TGSM pointer |
| 8 | +; that is not a GEP or bitcast) and any GEP / bitcast that consumes it |
| 9 | +; must be reported. |
| 10 | + |
| 11 | +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" |
| 12 | +target triple = "dxil-ms-dx" |
| 13 | + |
| 14 | +@"\01?GA@@3PAIA" = external addrspace(3) global [32 x i32], align 4 |
| 15 | +@"\01?GB@@3PAIA" = external addrspace(3) global [32 x i32], align 4 |
| 16 | + |
| 17 | +define void @main() { |
| 18 | +entry: |
| 19 | + %tid = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 0) |
| 20 | + %cond = icmp ult i32 %tid, 16 |
| 21 | + %ga = getelementptr [32 x i32], [32 x i32] addrspace(3)* @"\01?GA@@3PAIA", i32 0, i32 %tid |
| 22 | + %gb = getelementptr [32 x i32], [32 x i32] addrspace(3)* @"\01?GB@@3PAIA", i32 0, i32 %tid |
| 23 | + |
| 24 | + ; --- select between two TGSM GEPs, then chain a GEP through the select --- |
| 25 | + ; The select itself directly produces a TGSM pointer that is neither a |
| 26 | + ; GEP nor a bitcast, so it must be rejected. |
| 27 | + ; CHECK: error: TGSM pointers must originate from an unambiguous TGSM global variable. |
| 28 | + ; CHECK-NEXT: note: at '{{.*}}select{{.*}}' in block 'entry' of function 'main'. |
| 29 | + %sel = select i1 %cond, i32 addrspace(3)* %ga, i32 addrspace(3)* %gb |
| 30 | + ; A GEP that walks through the select must also be rejected: the chain |
| 31 | + ; walker stops at the select (not a GEP / bitcast / GlobalVariable). |
| 32 | + ; CHECK: error: TGSM pointers must originate from an unambiguous TGSM global variable. |
| 33 | + ; CHECK-NEXT: note: at '%sel_gep = getelementptr i32, i32 addrspace(3)* %sel, i32 0' in block 'entry' of function 'main'. |
| 34 | + %sel_gep = getelementptr i32, i32 addrspace(3)* %sel, i32 0 |
| 35 | + store i32 1, i32 addrspace(3)* %sel_gep, align 4 |
| 36 | + |
| 37 | + ; A bitcast that walks through the select must likewise be rejected. |
| 38 | + ; CHECK: error: TGSM pointers must originate from an unambiguous TGSM global variable. |
| 39 | + ; CHECK-NEXT: note: at '%sel_bc = bitcast i32 addrspace(3)* %sel to float addrspace(3)*' in block 'entry' of function 'main'. |
| 40 | + %sel_bc = bitcast i32 addrspace(3)* %sel to float addrspace(3)* |
| 41 | + store float 2.000000e+00, float addrspace(3)* %sel_bc, align 4 |
| 42 | + |
| 43 | + br i1 %cond, label %then, label %else |
| 44 | + |
| 45 | +then: |
| 46 | + %ga2 = getelementptr [32 x i32], [32 x i32] addrspace(3)* @"\01?GA@@3PAIA", i32 0, i32 %tid |
| 47 | + br label %merge |
| 48 | + |
| 49 | +else: |
| 50 | + %gb2 = getelementptr [32 x i32], [32 x i32] addrspace(3)* @"\01?GB@@3PAIA", i32 0, i32 %tid |
| 51 | + br label %merge |
| 52 | + |
| 53 | +merge: |
| 54 | + ; --- phi joining two TGSM GEPs, then chain a GEP/bitcast through the phi --- |
| 55 | + ; The phi itself produces an ambiguous TGSM pointer. |
| 56 | + ; CHECK: error: TGSM pointers must originate from an unambiguous TGSM global variable. |
| 57 | + ; CHECK-NEXT: note: at '{{.*}}phi{{.*}}' in block 'merge' of function 'main'. |
| 58 | + %p = phi i32 addrspace(3)* [ %ga2, %then ], [ %gb2, %else ] |
| 59 | + ; A GEP through the phi must be rejected: the chain walk reaches the |
| 60 | + ; phi which is neither a GEP, a bitcast, nor a GlobalVariable. |
| 61 | + ; CHECK: error: TGSM pointers must originate from an unambiguous TGSM global variable. |
| 62 | + ; CHECK-NEXT: note: at '%phi_gep = getelementptr i32, i32 addrspace(3)* %p, i32 0' in block 'merge' of function 'main'. |
| 63 | + %phi_gep = getelementptr i32, i32 addrspace(3)* %p, i32 0 |
| 64 | + store i32 3, i32 addrspace(3)* %phi_gep, align 4 |
| 65 | + |
| 66 | + ; Likewise a bitcast through the phi must be rejected, even when the |
| 67 | + ; chain has multiple GEP / bitcast hops before the phi appears. |
| 68 | + ; CHECK: error: TGSM pointers must originate from an unambiguous TGSM global variable. |
| 69 | + ; CHECK-NEXT: note: at '%phi_bc = bitcast i32 addrspace(3)* %phi_gep to float addrspace(3)*' in block 'merge' of function 'main'. |
| 70 | + %phi_bc = bitcast i32 addrspace(3)* %phi_gep to float addrspace(3)* |
| 71 | + store float 4.000000e+00, float addrspace(3)* %phi_bc, align 4 |
| 72 | + |
| 73 | + ; CHECK: Validation failed. |
| 74 | + ret void |
| 75 | +} |
| 76 | + |
| 77 | +declare i32 @dx.op.threadIdInGroup.i32(i32, i32) #0 |
| 78 | + |
| 79 | +attributes #0 = { nounwind readnone } |
| 80 | + |
| 81 | +!llvm.ident = !{!0} |
| 82 | +!dx.version = !{!1} |
| 83 | +!dx.valver = !{!2} |
| 84 | +!dx.shaderModel = !{!3} |
| 85 | +!dx.entryPoints = !{!4} |
| 86 | + |
| 87 | +!0 = !{!"dxc test"} |
| 88 | +!1 = !{i32 1, i32 9} |
| 89 | +!2 = !{i32 1, i32 10} |
| 90 | +!3 = !{!"cs", i32 6, i32 9} |
| 91 | +!4 = !{void ()* @main, !"main", null, null, !5} |
| 92 | +!5 = !{i32 4, !6} |
| 93 | +!6 = !{i32 64, i32 1, i32 1} |
0 commit comments