@@ -141,33 +141,44 @@ class TestLLVMSimulation:
141141
142142 def test_sim_api_with_llvm_simple (self ) -> None :
143143 """Test sim API with simple LLVM IR program."""
144- # Proper QIR-compliant LLVM IR
144+ # QIS format LLVM IR - uses i64 for qubit indices and qmain entry point
145+ # This matches the format that PECOS HUGR compiler generates
145146 llvm_ir = """
146147 ; ModuleID = 'quantum_test'
148+ source_filename = "quantum_test"
147149
148- %Qubit = type opaque
149- %Result = type opaque
150+ @str_c = constant [2 x i8] c"c\\ 00"
150151
151- declare void @__quantum__qis__h__body(%Qubit*)
152- declare %Result* @__quantum__qis__mz__body(%Qubit*)
153- declare %Qubit* @__quantum__rt__qubit_allocate()
154- declare void @__quantum__rt__qubit_release(%Qubit* )
155- declare void @__quantum__rt__result_record_output(%Result*, i8* )
152+ ; Entry point using qmain(i64)->i64 protocol
153+ define i64 @qmain(i64 %0) #0 {
154+ entry:
155+ ; Allocate qubit (returns i64 )
156+ %qubit = call i64 @__quantum__rt__qubit_allocate( )
156157
157- @0 = internal constant [2 x i8] c"c\\ 00"
158+ ; Apply H gate (takes i64 qubit index)
159+ call void @__quantum__qis__h__body(i64 %qubit)
158160
159- define void @main() #0 {
160- entry:
161- %qubit = call %Qubit* @__quantum__rt__qubit_allocate()
162- call void @__quantum__qis__h__body(%Qubit* %qubit)
163- %result = call %Result* @__quantum__qis__mz__body(%Qubit* %qubit)
164- call void @__quantum__rt__result_record_output(%Result* %result,
165- i8* getelementptr inbounds ([2 x i8], [2 x i8]* @0, i32 0, i32 0))
166- call void @__quantum__rt__qubit_release(%Qubit* %qubit)
167- ret void
161+ ; Allocate result handle
162+ %result_id = call i64 @__quantum__rt__result_allocate()
163+
164+ ; Measure qubit (returns i32 measurement)
165+ %measurement = call i32 @__quantum__qis__m__body(i64 %qubit, i64 %result_id)
166+
167+ ; Record output (convert i64 to i8* pointer for register name)
168+ %result_ptr = inttoptr i64 %result_id to i8*
169+ call void @__quantum__rt__result_record_output(i8* %result_ptr,
170+ i8* getelementptr inbounds ([2 x i8], [2 x i8]* @str_c, i32 0, i32 0))
171+
172+ ret i64 0
168173 }
169174
170- attributes #0 = { "EntryPoint" "requiredQubits"="1" }
175+ declare i64 @__quantum__rt__qubit_allocate()
176+ declare void @__quantum__qis__h__body(i64)
177+ declare i64 @__quantum__rt__result_allocate()
178+ declare i32 @__quantum__qis__m__body(i64, i64)
179+ declare void @__quantum__rt__result_record_output(i8*, i8*)
180+
181+ attributes #0 = { "EntryPoint" }
171182 """
172183
173184 try :
@@ -207,45 +218,53 @@ def test_sim_api_with_llvm_simple(self) -> None:
207218
208219 def test_sim_api_with_llvm_bell_state (self ) -> None :
209220 """Test sim API with Bell state in LLVM IR."""
210- # Bell state in QIS format - uses i64 qubit indices (not QIR opaque pointers)
211- # This is the format PECOS actually supports (from HUGR compilation)
221+ # QIS format LLVM IR - uses i64 for qubit indices and qmain entry point
222+ # This matches the format that PECOS HUGR compiler generates
212223 llvm_ir = """
213224 ; ModuleID = 'bell_state'
225+ source_filename = "bell_state"
214226
215- declare void @__quantum__qis__h__body(i64)
216- declare void @__quantum__qis__cnot__body(i64, i64)
217- declare i1 @__quantum__qis__mz__body(i64)
218- declare void @__quantum__rt__result_record_output(i64, i8*)
219-
220- @0 = internal constant [3 x i8] c"c0\\ 00"
221- @1 = internal constant [3 x i8] c"c1\\ 00"
227+ @str_c0 = constant [3 x i8] c"c0\\ 00"
228+ @str_c1 = constant [3 x i8] c"c1\\ 00"
222229
223- define void @main() #0 {
230+ ; Entry point using qmain(i64)->i64 protocol
231+ define i64 @qmain(i64 %0) #0 {
224232 entry:
225- ; Apply H to qubit 0
226- call void @__quantum__qis__h__body(i64 0)
227-
228- ; Apply CNOT(0, 1)
229- call void @__quantum__qis__cnot__body(i64 0, i64 1)
230-
231- ; Measure both qubits
232- %m0 = call i1 @__quantum__qis__mz__body(i64 0)
233- %m1 = call i1 @__quantum__qis__mz__body(i64 1)
234-
235- ; Convert i1 to i64 for result recording
236- %r0 = zext i1 %m0 to i64
237- %r1 = zext i1 %m1 to i64
233+ ; Allocate qubits (returns i64)
234+ %q0 = call i64 @__quantum__rt__qubit_allocate()
235+ %q1 = call i64 @__quantum__rt__qubit_allocate()
238236
239- ; Record results
240- call void @__quantum__rt__result_record_output(i64 %r0,
241- i8* getelementptr inbounds ([3 x i8], [3 x i8]* @0, i32 0, i32 0))
242- call void @__quantum__rt__result_record_output(i64 %r1,
243- i8* getelementptr inbounds ([3 x i8], [3 x i8]* @1, i32 0, i32 0))
244-
245- ret void
237+ ; Apply H to qubit 0
238+ call void @__quantum__qis__h__body(i64 %q0)
239+
240+ ; Apply CX(q0, q1)
241+ call void @__quantum__qis__cx__body(i64 %q0, i64 %q1)
242+
243+ ; Measure qubit 0
244+ %result_id0 = call i64 @__quantum__rt__result_allocate()
245+ %measurement0 = call i32 @__quantum__qis__m__body(i64 %q0, i64 %result_id0)
246+ %result_ptr0 = inttoptr i64 %result_id0 to i8*
247+ call void @__quantum__rt__result_record_output(i8* %result_ptr0,
248+ i8* getelementptr inbounds ([3 x i8], [3 x i8]* @str_c0, i32 0, i32 0))
249+
250+ ; Measure qubit 1
251+ %result_id1 = call i64 @__quantum__rt__result_allocate()
252+ %measurement1 = call i32 @__quantum__qis__m__body(i64 %q1, i64 %result_id1)
253+ %result_ptr1 = inttoptr i64 %result_id1 to i8*
254+ call void @__quantum__rt__result_record_output(i8* %result_ptr1,
255+ i8* getelementptr inbounds ([3 x i8], [3 x i8]* @str_c1, i32 0, i32 0))
256+
257+ ret i64 0
246258 }
247259
248- attributes #0 = { "EntryPoint" "requiredQubits"="2" }
260+ declare i64 @__quantum__rt__qubit_allocate()
261+ declare void @__quantum__qis__h__body(i64)
262+ declare void @__quantum__qis__cx__body(i64, i64)
263+ declare i64 @__quantum__rt__result_allocate()
264+ declare i32 @__quantum__qis__m__body(i64, i64)
265+ declare void @__quantum__rt__result_record_output(i8*, i8*)
266+
267+ attributes #0 = { "EntryPoint" }
249268 """
250269
251270 try :
0 commit comments