106 changes: 106 additions & 0 deletions llvm/test/CodeGen/AArch64/multi-vector-load-size.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
; RUN: llc -mtriple=aarch64-linux-gnu -stop-after=instruction-select < %s | FileCheck %s

%struct.__neon_float32x2x2_t = type { <2 x float>, <2 x float> }
%struct.__neon_float32x2x3_t = type { <2 x float>, <2 x float>, <2 x float> }
%struct.__neon_float32x2x4_t = type { <2 x float>, <2 x float>, <2 x float>, <2 x float> }

declare %struct.__neon_float32x2x2_t @llvm.aarch64.neon.ld2.v2f32.p0f32(float*)
declare %struct.__neon_float32x2x3_t @llvm.aarch64.neon.ld3.v2f32.p0f32(float*)
declare %struct.__neon_float32x2x4_t @llvm.aarch64.neon.ld4.v2f32.p0f32(float*)

declare %struct.__neon_float32x2x2_t @llvm.aarch64.neon.ld1x2.v2f32.p0f32(float*)
declare %struct.__neon_float32x2x3_t @llvm.aarch64.neon.ld1x3.v2f32.p0f32(float*)
declare %struct.__neon_float32x2x4_t @llvm.aarch64.neon.ld1x4.v2f32.p0f32(float*)

declare %struct.__neon_float32x2x2_t @llvm.aarch64.neon.ld2r.v2f32.p0f32(float*)
declare %struct.__neon_float32x2x3_t @llvm.aarch64.neon.ld3r.v2f32.p0f32(float*)
declare %struct.__neon_float32x2x4_t @llvm.aarch64.neon.ld4r.v2f32.p0f32(float*)

declare %struct.__neon_float32x2x2_t @llvm.aarch64.neon.ld2lane.v2f32.p0f32(<2 x float>, <2 x float>, i64, float*)
declare %struct.__neon_float32x2x3_t @llvm.aarch64.neon.ld3lane.v2f32.p0f32(<2 x float>, <2 x float>, <2 x float>, i64, float*)
declare %struct.__neon_float32x2x4_t @llvm.aarch64.neon.ld4lane.v2f32.p0f32(<2 x float>, <2 x float>, <2 x float>, <2 x float>, i64, float*)


define %struct.__neon_float32x2x2_t @test_ld2(float* %addr) {
; CHECK-LABEL: name: test_ld2
; CHECK: LD2Twov2s {{.*}} :: (load (s128) {{.*}})
%val = call %struct.__neon_float32x2x2_t @llvm.aarch64.neon.ld2.v2f32.p0f32(float* %addr)
ret %struct.__neon_float32x2x2_t %val
}

define %struct.__neon_float32x2x3_t @test_ld3(float* %addr) {
; CHECK-LABEL: name: test_ld3
; CHECK: LD3Threev2s {{.*}} :: (load (s192) {{.*}})
%val = call %struct.__neon_float32x2x3_t @llvm.aarch64.neon.ld3.v2f32.p0f32(float* %addr)
ret %struct.__neon_float32x2x3_t %val
}

define %struct.__neon_float32x2x4_t @test_ld4(float* %addr) {
; CHECK-LABEL: name: test_ld4
; CHECK: LD4Fourv2s {{.*}} :: (load (s256) {{.*}})
%val = call %struct.__neon_float32x2x4_t @llvm.aarch64.neon.ld4.v2f32.p0f32(float* %addr)
ret %struct.__neon_float32x2x4_t %val
}

define %struct.__neon_float32x2x2_t @test_ld1x2(float* %addr) {
; CHECK-LABEL: name: test_ld1x2
; CHECK: LD1Twov2s {{.*}} :: (load (s128) {{.*}})
%val = call %struct.__neon_float32x2x2_t @llvm.aarch64.neon.ld1x2.v2f32.p0f32(float* %addr)
ret %struct.__neon_float32x2x2_t %val
}

define %struct.__neon_float32x2x3_t @test_ld1x3(float* %addr) {
; CHECK-LABEL: name: test_ld1x3
; CHECK: LD1Threev2s {{.*}} :: (load (s192) {{.*}})
%val = call %struct.__neon_float32x2x3_t @llvm.aarch64.neon.ld1x3.v2f32.p0f32(float* %addr)
ret %struct.__neon_float32x2x3_t %val
}

define %struct.__neon_float32x2x4_t @test_ld1x4(float* %addr) {
; CHECK-LABEL: name: test_ld1x4
; CHECK: LD1Fourv2s {{.*}} :: (load (s256) {{.*}})
%val = call %struct.__neon_float32x2x4_t @llvm.aarch64.neon.ld1x4.v2f32.p0f32(float* %addr)
ret %struct.__neon_float32x2x4_t %val
}

define %struct.__neon_float32x2x2_t @test_ld2r(float* %addr) {
; CHECK-LABEL: name: test_ld2r
; CHECK: LD2Rv2s {{.*}} :: (load (s64) {{.*}})
%val = call %struct.__neon_float32x2x2_t @llvm.aarch64.neon.ld2r.v2f32.p0f32(float* %addr)
ret %struct.__neon_float32x2x2_t %val
}

define %struct.__neon_float32x2x3_t @test_ld3r(float* %addr) {
; CHECK-LABEL: name: test_ld3r
; CHECK: LD3Rv2s {{.*}} :: (load (s96) {{.*}})
%val = call %struct.__neon_float32x2x3_t @llvm.aarch64.neon.ld3r.v2f32.p0f32(float* %addr)
ret %struct.__neon_float32x2x3_t %val
}

define %struct.__neon_float32x2x4_t @test_ld4r(float* %addr) {
; CHECK-LABEL: name: test_ld4r
; CHECK: LD4Rv2s {{.*}} :: (load (s128) {{.*}})
%val = call %struct.__neon_float32x2x4_t @llvm.aarch64.neon.ld4r.v2f32.p0f32(float* %addr)
ret %struct.__neon_float32x2x4_t %val
}

define %struct.__neon_float32x2x2_t @test_ld2lane(<2 x float> %a, <2 x float> %b, float* %addr) {
; CHECK-LABEL: name: test_ld2lane
; CHECK: {{.*}} LD2i32 {{.*}}
%val = call %struct.__neon_float32x2x2_t @llvm.aarch64.neon.ld2lane.v2f32.p0f32(<2 x float> %a, <2 x float> %b, i64 1, float* %addr)
ret %struct.__neon_float32x2x2_t %val
}

define %struct.__neon_float32x2x3_t @test_ld3lane(<2 x float> %a, <2 x float> %b, <2 x float> %c, float* %addr) {
; CHECK-LABEL: name: test_ld3lane
; CHECK: {{.*}} LD3i32 {{.*}}
%val = call %struct.__neon_float32x2x3_t @llvm.aarch64.neon.ld3lane.v2f32.p0f32(<2 x float> %a, <2 x float> %b, <2 x float> %c, i64 1, float* %addr)
ret %struct.__neon_float32x2x3_t %val
}

define %struct.__neon_float32x2x4_t @test_ld4lane(<2 x float> %a, <2 x float> %b, <2 x float> %c, <2 x float> %d, float* %addr) {
; CHECK-LABEL: name: test_ld4lane
; CHECK: {{.*}} LD4i32 {{.*}}
%val = call %struct.__neon_float32x2x4_t @llvm.aarch64.neon.ld4lane.v2f32.p0f32(<2 x float> %a, <2 x float> %b, <2 x float> %c, <2 x float> %d, i64 1, float* %addr)
ret %struct.__neon_float32x2x4_t %val
}
12 changes: 3 additions & 9 deletions llvm/test/CodeGen/AArch64/multi-vector-store-size.ll
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ define void @addstx(ptr %res, ptr %a, ptr %b, ptr %c, ptr %d) {
%cr = fadd <4 x float> %cl, %dl
%dr = fadd <4 x float> %dl, %al

; The sizes below are conservative. AArch64TargetLowering
; conservatively assumes the entire vector is stored.
tail call void @llvm.aarch64.neon.st2.v4f32.p0(<4 x float> %ar, <4 x float> %br, ptr %res)
; CHECK: ST2Twov4s {{.*}} :: (store (s256) {{.*}})
tail call void @llvm.aarch64.neon.st3.v4f32.p0(<4 x float> %ar, <4 x float> %br, <4 x float> %cr, ptr %res)
Expand All @@ -46,8 +44,6 @@ define void @addst1x(ptr %res, ptr %a, ptr %b, ptr %c, ptr %d) {
%cr = fadd <4 x float> %cl, %dl
%dr = fadd <4 x float> %dl, %al

; The sizes below are conservative. AArch64TargetLowering
; conservatively assumes the entire vector is stored.
tail call void @llvm.aarch64.neon.st1x2.v4f32.p0(<4 x float> %ar, <4 x float> %br, ptr %res)
; CHECK: ST1Twov4s {{.*}} :: (store (s256) {{.*}})
tail call void @llvm.aarch64.neon.st1x3.v4f32.p0(<4 x float> %ar, <4 x float> %br, <4 x float> %cr, ptr %res)
Expand All @@ -69,14 +65,12 @@ define void @addstxlane(ptr %res, ptr %a, ptr %b, ptr %c, ptr %d) {
%cr = fadd <4 x float> %cl, %dl
%dr = fadd <4 x float> %dl, %al

; The sizes below are conservative. AArch64TargetLowering
; conservatively assumes the entire vector is stored.
tail call void @llvm.aarch64.neon.st2lane.v4f32.p0(<4 x float> %ar, <4 x float> %br, i64 1, ptr %res)
; CHECK: ST2i32 {{.*}} :: (store (s256) {{.*}})
; CHECK: ST2i32 {{.*}} :: (store (s64) {{.*}})
tail call void @llvm.aarch64.neon.st3lane.v4f32.p0(<4 x float> %ar, <4 x float> %br, <4 x float> %cr, i64 1, ptr %res)
; CHECK: ST3i32 {{.*}} :: (store (s384) {{.*}})
; CHECK: ST3i32 {{.*}} :: (store (s96) {{.*}})
tail call void @llvm.aarch64.neon.st4lane.v4f32.p0(<4 x float> %ar, <4 x float> %br, <4 x float> %cr, <4 x float> %dr, i64 1, ptr %res)
; CHECK: ST4i32 {{.*}} :: (store (s512) {{.*}})
; CHECK: ST4i32 {{.*}} :: (store (s128) {{.*}})

ret void
}
1 change: 1 addition & 0 deletions llvm/test/tools/llvm-rc/windres-preproc.test
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
; REQUIRES: shell

; RUN: llvm-windres -### --include-dir %p/incdir1 --include %p/incdir2 "-DFOO1=\\\"foo bar\\\"" -UFOO2 -D FOO3 --preprocessor-arg "-DFOO4=\\\"baz baz\\\"" -DFOO5=\"bar\" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK1
; RUN: llvm-windres -### --include-dir %p/incdir1 --include %p/incdir2 "-DFOO1=\"foo bar\"" -UFOO2 -D FOO3 --preprocessor-arg "-DFOO4=\"baz baz\"" "-DFOO5=bar" %p/Inputs/empty.rc %t.res --use-temp-file | FileCheck %s --check-prefix=CHECK1
; CHECK1: {{^}} "clang" "--driver-mode=gcc" "-target" "{{.*}}-{{.*}}{{mingw32|windows-gnu}}" "-E" "-xc" "-DRC_INVOKED" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc" "-I" "{{.*}}incdir1" "-I" "{{.*}}incdir2" "-D" "FOO1=\"foo bar\"" "-U" "FOO2" "-D" "FOO3" "-DFOO4=\"baz baz\"" "-D" "FOO5=bar"{{$}}
; RUN: llvm-windres -### --preprocessor "i686-w64-mingw32-gcc -E -DFOO=\\\"foo\\ bar\\\"" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK2
; CHECK2: {{^}} "i686-w64-mingw32-gcc" "-E" "-DFOO=\"foo bar\"" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
7 changes: 4 additions & 3 deletions llvm/tools/llvm-rc/WindresOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ defm codepage : LongShort<"c", "codepage", "Default codepage to use">;

defm language : LongShort<"l", "language", "Default language to use (0x0-0xffff)">;

def use_temp_file: Flag<["--"], "use-temp-file">,
HelpText<"Mimic GNU windres preprocessor option handling "
"(don't unescape preprocessor options)">;

defm verbose : F<"v", "verbose", "Enable verbose output">;
defm version : F<"V", "version", "Display version">;

Expand All @@ -57,6 +61,3 @@ defm help : F<"h", "help", "Display this message and exit">;
def _HASH_HASH_HASH : Flag<["-"], "###">;

def no_preprocess : Flag<["--"], "no-preprocess">;

// Unimplemented options for compatibility
def use_temp_file: Flag<["--"], "use-temp-file">;
17 changes: 13 additions & 4 deletions llvm/tools/llvm-rc/llvm-rc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,14 @@ RcOptions parseWindresOptions(ArrayRef<const char *> ArgsArr,
// done this double escaping) probably is confined to cases like these
// quoted string defines, and those happen to work the same across unix
// and windows.
std::string Unescaped = unescape(Arg->getValue());
//
// If GNU windres is executed with --use-temp-file, it doesn't use
// popen() to invoke the preprocessor, but uses another function which
// actually preserves tricky characters better. To mimic this behaviour,
// don't unescape arguments here.
std::string Value = Arg->getValue();
if (!InputArgs.hasArg(WINDRES_use_temp_file))
Value = unescape(Value);
switch (Arg->getOption().getID()) {
case WINDRES_include_dir:
// Technically, these are handled the same way as e.g. defines, but
Expand All @@ -487,17 +494,19 @@ RcOptions parseWindresOptions(ArrayRef<const char *> ArgsArr,
break;
case WINDRES_define:
Opts.PreprocessArgs.push_back("-D");
Opts.PreprocessArgs.push_back(Unescaped);
Opts.PreprocessArgs.push_back(Value);
break;
case WINDRES_undef:
Opts.PreprocessArgs.push_back("-U");
Opts.PreprocessArgs.push_back(Unescaped);
Opts.PreprocessArgs.push_back(Value);
break;
case WINDRES_preprocessor_arg:
Opts.PreprocessArgs.push_back(Unescaped);
Opts.PreprocessArgs.push_back(Value);
break;
}
}
// TODO: If --use-temp-file is set, we shouldn't be unescaping
// the --preprocessor argument either, only splitting it.
if (InputArgs.hasArg(WINDRES_preprocessor))
Opts.PreprocessCmd =
unescapeSplit(InputArgs.getLastArgValue(WINDRES_preprocessor));
Expand Down