def LLVM_FRemOp : LLVM_ArithmeticOp<"frem", "CreateFRem">;
// Memory-related operations.
-def LLVM_AllocaOp : LLVM_OneResultOp<"alloca">,
- Arguments<(ins LLVM_Type:$arraySize)> {
+def LLVM_AllocaOp :
+ LLVM_OneResultOp<"alloca">,
+ Arguments<(ins LLVM_Type:$arraySize, OptionalAttr<I64Attr>:$alignment)> {
string llvmBuilder = [{
- $res = builder.CreateAlloca($_resultType->getPointerElementType(),
- $arraySize);
+ auto *alloca = builder.CreateAlloca(
+ $_resultType->getPointerElementType(), $arraySize);
+ if ($alignment.hasValue()) {
+ auto align = $alignment.getValue().getZExtValue();
+ if (align != 0)
+ alloca->setAlignment(align);
+ }
+ $res = alloca;
}];
+ let builders = [OpBuilder<
+ "Builder *b, OperationState *result, Type resultType, Value *arraySize,"
+ "unsigned alignment = 0",
+ [{
+ if (!alignment)
+ return build(b, result, resultType, arraySize, IntegerAttr());
+ auto *ctx = resultType.getContext();
+ auto align = IntegerAttr::get(IntegerType::get(64, ctx), alignment);
+ build(b, result, resultType, arraySize, align);
+ }]>];
let parser = [{ return parseAllocaOp(parser, result); }];
let printer = [{ printAllocaOp(p, *this); }];
+ let verifier = [{
+ if (alignment().hasValue()) {
+ auto align = alignment().getValue().getSExtValue();
+ if (align < 0)
+ return emitOpError("expected positive alignment");
+ }
+ return success();
+ }];
}
def LLVM_GEPOp : LLVM_OneResultOp<"getelementptr", [NoSideEffect]>,
Arguments<(ins LLVM_Type:$base, Variadic<LLVM_Type>:$indices)>,
// -----
+func @alloca_nonpositive_alignment(%size : !llvm.i64) {
+ // expected-error@+1 {{expected positive alignment}}
+ llvm.alloca %size x !llvm.i32 {alignment = -1} : (!llvm.i64) -> (!llvm<"i32*">)
+}
+
+// -----
+
func @gep_missing_input_result_type(%pos : !llvm.i64, %base : !llvm<"float*">) {
// expected-error@+1 {{expected trailing function type with at least one argument and one result}}
llvm.getelementptr %base[%pos] : () -> ()
%2 = llvm.shufflevector %arg0, %arg0 [0 : i32, 0 : i32, 0 : i32, 0 : i32, 7 : i32] : !llvm<"<4 x float>">, !llvm<"<4 x float>">
return
}
+
+// CHECK-LABEL: @alloca
+func @alloca(%size : !llvm.i64) {
+ // CHECK: llvm.alloca %{{.*}} x !llvm.i32 : (!llvm.i64) -> !llvm<"i32*">
+ llvm.alloca %size x !llvm.i32 {alignment = 0} : (!llvm.i64) -> (!llvm<"i32*">)
+ // CHECK-NEXT: llvm.alloca %{{.*}} x !llvm.i32 {alignment = 8 : i64} : (!llvm.i64) -> !llvm<"i32*">
+ llvm.alloca %size x !llvm.i32 {alignment = 8} : (!llvm.i64) -> (!llvm<"i32*">)
+ llvm.return
+}
%2 = llvm.shufflevector %arg0, %arg0 [0 : i32, 0 : i32, 0 : i32, 0 : i32, 7 : i32] : !llvm<"<4 x float>">, !llvm<"<4 x float>">
llvm.return
}
+
+// CHECK-LABEL: @alloca
+func @alloca(%size : !llvm.i64) {
+ // CHECK: alloca
+ // CHECK-NOT: align
+ llvm.alloca %size x !llvm.i32 {alignment = 0} : (!llvm.i64) -> (!llvm<"i32*">)
+ // CHECK-NEXT: alloca {{.*}} align 8
+ llvm.alloca %size x !llvm.i32 {alignment = 8} : (!llvm.i64) -> (!llvm<"i32*">)
+ llvm.return
+}