From: Benjamin Kramer Date: Mon, 20 Jul 2015 15:31:17 +0000 (+0000) Subject: [CodeGen] Flip lanes when lowering __builtin_palignr with one lane X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d6eac0533570da52e03b5629c8dccae0b7f7a970;p=clang [CodeGen] Flip lanes when lowering __builtin_palignr with one lane Otherwise we'd pick the wrong lane for the resulting shuffle and miscompile code. PR24187. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242678 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 9e53870317..463b3eee3d 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -6238,6 +6238,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, // but less than two lanes, convert to shifting in zeroes. if (ShiftVal > NumLaneElts) { ShiftVal -= NumLaneElts; + Ops[1] = Ops[0]; Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType()); } diff --git a/test/CodeGen/palignr.c b/test/CodeGen/palignr.c index 1712df5256..5a77597c34 100644 --- a/test/CodeGen/palignr.c +++ b/test/CodeGen/palignr.c @@ -4,13 +4,13 @@ #define _mm_alignr_epi8(a, b, n) (__builtin_ia32_palignr128((a), (b), (n))) typedef __attribute__((vector_size(16))) int int4; -// CHECK: palignr +// CHECK: palignr $15, %xmm1, %xmm0 int4 align1(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 15); } // CHECK: ret // CHECK: ret // CHECK-NOT: palignr int4 align2(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 16); } -// CHECK: psrldq +// CHECK: psrldq $1, %xmm0 int4 align3(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 17); } // CHECK: xor int4 align4(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 32); }