Skip to content

Comments

Fixed bug: load array or struct variable failed at AssignStmt.#22

Open
OrchidRock wants to merge 1 commit intoPacktPublishing:masterfrom
OrchidRock:fix_aggrate_type_ref
Open

Fixed bug: load array or struct variable failed at AssignStmt.#22
OrchidRock wants to merge 1 commit intoPacktPublishing:masterfrom
OrchidRock:fix_aggrate_type_ref

Conversation

@OrchidRock
Copy link

For the following input program to tinylang:

MODULE Point;

TYPE Point = RECORD X, Y: INTEGER END;

VAR p: Point;

PROCEDURE AssignX(a: INTEGER);
BEGIN
  p.X := a;
  p.Y := p.X + a;
END AssignX;

END Point.

I got a program crash:

tinylang: /usr/lib/llvm-12/include/llvm/Support/Casting.h:269: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = llvm::PointerType; Y = llvm::Type; typename llvm::cast_retty<X, Y*>::ret_type = llvm::PointerType*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

it came from the struct reference for p.Xat p.Y := p.X + a. The program calls readVariable method when emitting p.X expression, but it didn't send the argument for LoadVal. After I fixed it, the program is working.

However, It's not enough. Then I got the following IR code:

; ModuleID = 'Point.mod'
source_filename = "Point.mod"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

%Point = type { i64, i64 }

@_t5Point1p = private global %Point zeroinitializer

define void @_t5Point7AssignX(i64 %a) {
entry:
  store i64 %a, i64* getelementptr inbounds (%Point, %Point* @_t5Point1p, i32 0, i32 0), align 8
  %0 = load %Point, %Point* @_t5Point1p, align 8
  %1 = add nsw %Point %0, i64 %a
  store %Point %1, i64* getelementptr inbounds (%Point, %Point* @_t5Point1p, i32 0, i32 1), align 8
  ret void
}

But the load instruction is incorrect because we didn't construct the correct IdxList when calling Builder::CreateInBoundsGEP(val, IdxList) .

After fixed the program, I got the working IR code:

; ModuleID = 'Point.mod'
source_filename = "Point.mod"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

%Point = type { i64, i64 }

@_t5Point1p = private global %Point zeroinitializer

define void @_t5Point7AssignX(i64 %a) {
entry:
  store i64 %a, i64* getelementptr inbounds (%Point, %Point* @_t5Point1p, i32 0, i32 0), align 8
  %0 = load i64, i64* getelementptr inbounds (%Point, %Point* @_t5Point1p, i32 0, i32 0), align 8
  %1 = add nsw  %0, i64 %a
  store i64 %1, i64* getelementptr inbounds (%Point, %Point* @_t5Point1p, i32 0, i32 1), align 8
  ret void
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant