1; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV 2 3; TODO(#60133): Requires updates following opaque pointer migration. 4; XFAIL: * 5 6%struct.ST = type { i32, i32, i32 } 7 8; CHECK-SPIRV: OpName %[[#struct:]] "struct.ST" 9; CHECK-SPIRV: %[[#int:]] = OpTypeInt 32 0 10; CHECK-SPIRV: %[[#intP:]] = OpTypePointer Function %[[#int]] 11; CHECK-SPIRV: %[[#struct]] = OpTypeStruct %[[#int]] %[[#int]] %[[#int]] 12; CHECK-SPIRV: %[[#structP:]] = OpTypePointer Function %[[#struct]] 13; CHECK-SPIRV: %[[#structPP:]] = OpTypePointer Function %[[#structP]] 14; CHECK-SPIRV: %[[#zero:]] = OpConstant %[[#int]] 0 15; CHECK-SPIRV: %[[#one:]] = OpConstant %[[#int]] 1 16; CHECK-SPIRV: %[[#two:]] = OpConstant %[[#int]] 2 17 18define dso_local spir_func i32 @cmp_func(i8* %p1, i8* %p2) { 19entry: 20 %retval = alloca i32, align 4 21 %p1.addr = alloca i8*, align 8 22 %p2.addr = alloca i8*, align 8 23; CHECK-SPIRV: %[[#s1:]] = OpVariable %[[#structPP]] 24; CHECK-SPIRV: %[[#s2:]] = OpVariable %[[#structPP]] 25 %s1 = alloca %struct.ST*, align 8 26 %s2 = alloca %struct.ST*, align 8 27 store i8* %p1, i8** %p1.addr, align 8 28 store i8* %p2, i8** %p2.addr, align 8 29 %0 = load i8*, i8** %p1.addr, align 8 30; CHECK-SPIRV: %[[#t1:]] = OpBitcast %[[#structP]] 31; CHECK-SPIRV: OpStore %[[#s1]] %[[#t1]] 32 %1 = bitcast i8* %0 to %struct.ST* 33 store %struct.ST* %1, %struct.ST** %s1, align 8 34 %2 = load i8*, i8** %p2.addr, align 8 35; CHECK-SPIRV: %[[#t2:]] = OpBitcast %[[#structP]] 36; CHECK-SPIRV: OpStore %[[#s2]] %[[#t2]] 37 %3 = bitcast i8* %2 to %struct.ST* 38 store %struct.ST* %3, %struct.ST** %s2, align 8 39; CHECK-SPIRV: %[[#t3:]] = OpLoad %[[#structP]] %[[#s1]] 40; CHECK-SPIRV: %[[#a1:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t3]] %[[#zero]] %[[#zero]] 41; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#a1]] 42 %4 = load %struct.ST*, %struct.ST** %s1, align 8 43 %a = getelementptr inbounds %struct.ST, %struct.ST* %4, i32 0, i32 0 44 %5 = load i32, i32* %a, align 4 45; CHECK-SPIRV: %[[#t4:]] = OpLoad %[[#structP]] %[[#s2]] 46; CHECK-SPIRV: %[[#a2:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t4]] %[[#zero]] %[[#zero]] 47; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#a2]] 48 %6 = load %struct.ST*, %struct.ST** %s2, align 8 49 %a1 = getelementptr inbounds %struct.ST, %struct.ST* %6, i32 0, i32 0 50 %7 = load i32, i32* %a1, align 4 51 %cmp = icmp ne i32 %5, %7 52 br i1 %cmp, label %if.then, label %if.end 53 54if.then: ; preds = %entry 55; CHECK-SPIRV: %[[#t5:]] = OpLoad %[[#structP]] %[[#s1]] 56; CHECK-SPIRV: %[[#a_1:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t5]] %[[#zero]] %[[#zero]] 57; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#a_1]] 58 %8 = load %struct.ST*, %struct.ST** %s1, align 8 59 %a2 = getelementptr inbounds %struct.ST, %struct.ST* %8, i32 0, i32 0 60 %9 = load i32, i32* %a2, align 4 61; CHECK-SPIRV: %[[#t6:]] = OpLoad %[[#structP]] %[[#s2]] 62; CHECK-SPIRV: %[[#a_2:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t6]] %[[#zero]] %[[#zero]] 63; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#a_2]] 64 %10 = load %struct.ST*, %struct.ST** %s2, align 8 65 %a3 = getelementptr inbounds %struct.ST, %struct.ST* %10, i32 0, i32 0 66 %11 = load i32, i32* %a3, align 4 67 %sub = sub nsw i32 %9, %11 68 store i32 %sub, i32* %retval, align 4 69 br label %return 70 71if.end: ; preds = %entry 72; CHECK-SPIRV: %[[#t7:]] = OpLoad %[[#structP]] %[[#s1]] 73; CHECK-SPIRV: %[[#b1:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t7]] %[[#zero]] %[[#one]] 74; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#b1]] 75 %12 = load %struct.ST*, %struct.ST** %s1, align 8 76 %b = getelementptr inbounds %struct.ST, %struct.ST* %12, i32 0, i32 1 77 %13 = load i32, i32* %b, align 4 78; CHECK-SPIRV: %[[#t8:]] = OpLoad %[[#structP]] %[[#s2]] 79; CHECK-SPIRV: %[[#b2:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t8]] %[[#zero]] %[[#one]] 80; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#b2]] 81 %14 = load %struct.ST*, %struct.ST** %s2, align 8 82 %b4 = getelementptr inbounds %struct.ST, %struct.ST* %14, i32 0, i32 1 83 %15 = load i32, i32* %b4, align 4 84 %cmp5 = icmp ne i32 %13, %15 85 br i1 %cmp5, label %if.then6, label %if.end10 86 87if.then6: ; preds = %if.end 88; CHECK-SPIRV: %[[#t9:]] = OpLoad %[[#structP]] %[[#s1]] 89; CHECK-SPIRV: %[[#b_1:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t9]] %[[#zero]] %[[#one]] 90; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#b_1]] 91 %16 = load %struct.ST*, %struct.ST** %s1, align 8 92 %b7 = getelementptr inbounds %struct.ST, %struct.ST* %16, i32 0, i32 1 93 %17 = load i32, i32* %b7, align 4 94; CHECK-SPIRV: %[[#t10:]] = OpLoad %[[#structP]] %[[#s2]] 95; CHECK-SPIRV: %[[#b_2:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t10]] %[[#zero]] %[[#one]] 96; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#b_2]] 97 %18 = load %struct.ST*, %struct.ST** %s2, align 8 98 %b8 = getelementptr inbounds %struct.ST, %struct.ST* %18, i32 0, i32 1 99 %19 = load i32, i32* %b8, align 4 100 %sub9 = sub nsw i32 %17, %19 101 store i32 %sub9, i32* %retval, align 4 102 br label %return 103 104if.end10: ; preds = %if.end 105; CHECK-SPIRV: %[[#t11:]] = OpLoad %[[#structP]] %[[#s1]] 106; CHECK-SPIRV: %[[#c1:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t11]] %[[#zero]] %[[#two]] 107; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#c1]] 108 %20 = load %struct.ST*, %struct.ST** %s1, align 8 109 %c = getelementptr inbounds %struct.ST, %struct.ST* %20, i32 0, i32 2 110 %21 = load i32, i32* %c, align 4 111; CHECK-SPIRV: %[[#t12:]] = OpLoad %[[#structP]] %[[#s2]] 112; CHECK-SPIRV: %[[#c2:]] = OpInBoundsPtrAccessChain %[[#intP]] %[[#t12]] %[[#zero]] %[[#two]] 113; CHECK-SPIRV: %[[#]] = OpLoad %[[#int]] %[[#c2]] 114 %22 = load %struct.ST*, %struct.ST** %s2, align 8 115 %c11 = getelementptr inbounds %struct.ST, %struct.ST* %22, i32 0, i32 2 116 %23 = load i32, i32* %c11, align 4 117 %sub12 = sub nsw i32 %21, %23 118 store i32 %sub12, i32* %retval, align 4 119 br label %return 120 121return: ; preds = %if.end10, %if.then6, %if.then 122 %24 = load i32, i32* %retval, align 4 123 ret i32 %24 124} 125