diff --git a/tools/clang/lib/CodeGen/CGExprCXX.cpp b/tools/clang/lib/CodeGen/CGExprCXX.cpp index 5c0158210..1dacdef7e 100644 --- a/tools/clang/lib/CodeGen/CGExprCXX.cpp +++ b/tools/clang/lib/CodeGen/CGExprCXX.cpp @@ -221,7 +221,32 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( llvm::Value *This = nullptr; if (Base->getValueKind() != ExprValueKind::VK_RValue) { - This = EmitLValue(Base).getAddress(); + LValue LV = EmitLValue(Base); + if (LV.isSimple()) { + This = EmitLValue(Base).getAddress(); + if (isa(Base)) { + llvm::Value *Val = Builder.CreateLoad(This); + This = Builder.CreateAlloca(Val->getType()); + Builder.CreateStore(Val, This); + } + } else { + assert(LV.isExtVectorElt() && "must be ext vector here"); + This = LV.getExtVectorAddr(); + llvm::Constant *Elts = LV.getExtVectorElts(); + llvm::Type *Ty = ConvertType(LV.getType()); + + llvm::Constant *zero = Builder.getInt32(0); + llvm::Value *TmpThis = Builder.CreateAlloca(Ty); + for (unsigned i = 0; i < Ty->getVectorNumElements(); i++) { + llvm::Value *EltIdx = Elts->getAggregateElement(i); + llvm::Value *EltGEP = Builder.CreateGEP(This, {zero, EltIdx}); + llvm::Value *TmpEltGEP = + Builder.CreateGEP(TmpThis, {zero, Builder.getInt32(i)}); + llvm::Value *Elt = Builder.CreateLoad(EltGEP); + Builder.CreateStore(Elt, TmpEltGEP); + } + This = TmpThis; + } } else { llvm::Value *Val = EmitScalarExpr(Base); This = Builder.CreateAlloca(Val->getType()); diff --git a/tools/clang/test/CodeGenHLSL/swizzleIndexing.hlsl b/tools/clang/test/CodeGenHLSL/swizzleIndexing.hlsl new file mode 100644 index 000000000..0c953e38f --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/swizzleIndexing.hlsl @@ -0,0 +1,10 @@ +// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s + +// CHECK: @main + +float4x4 m; +uint4 main(uint4 a : AAA, uint4 b : BBB) : SV_Target +{ + float4x4 tm = m; + return a.wzyx[b.x] + tm._m00_m11[b.x]; +} diff --git a/tools/clang/unittests/HLSL/CompilerTest.cpp b/tools/clang/unittests/HLSL/CompilerTest.cpp index c60c7e51b..9fc712c06 100644 --- a/tools/clang/unittests/HLSL/CompilerTest.cpp +++ b/tools/clang/unittests/HLSL/CompilerTest.cpp @@ -529,6 +529,7 @@ public: TEST_METHOD(CodeGenSwizzle2) TEST_METHOD(CodeGenSwizzleAtomic) TEST_METHOD(CodeGenSwizzleAtomic2) + TEST_METHOD(CodeGenSwizzleIndexing) TEST_METHOD(CodeGenTemp1) TEST_METHOD(CodeGenTemp2) TEST_METHOD(CodeGenTexSubscript) @@ -2811,6 +2812,10 @@ TEST_F(CompilerTest, CodeGenSwizzleAtomic2) { CodeGenTestCheck(L"..\\CodeGenHLSL\\swizzleAtomic2.hlsl"); } +TEST_F(CompilerTest, CodeGenSwizzleIndexing) { + CodeGenTestCheck(L"..\\CodeGenHLSL\\swizzleIndexing.hlsl"); +} + TEST_F(CompilerTest, CodeGenTemp1) { CodeGenTest(L"..\\CodeGenHLSL\\temp1.hlsl"); }