diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp --- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp +++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp @@ -811,6 +811,15 @@ // New load can be generated Value *Load1Ptr = LI1->getPointerOperand(); Builder.SetInsertPoint(LI1); + if (!cast(Load1Ptr->getType())->isOpaque()) { + // We require an extra bitcast for non-opaque cases + unsigned Load1AS = + cast(Load1Ptr->getType())->getAddressSpace(); + Load1Ptr = Builder.CreateBitCast( + Load1Ptr, + PointerType::get( + IntegerType::get(Load1Ptr->getContext(), LOps.LoadSize), Load1AS)); + } NewLoad = Builder.CreateAlignedLoad( IntegerType::get(Load1Ptr->getContext(), LOps.LoadSize), Load1Ptr, LI1->getAlign(), LI1->isVolatile(), ""); diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/non-opaque-or-load.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/non-opaque-or-load.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/AggressiveInstCombine/X86/non-opaque-or-load.ll @@ -0,0 +1,30 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=aggressive-instcombine -mtriple x86_64-none-eabi -mattr=avx2 -data-layout="e-n64" -S | FileCheck %s --check-prefixes=LE +; RUN: opt < %s -passes=aggressive-instcombine -mtriple x86_64-none-eabi -mattr=avx2 -data-layout="E-n64" -S | FileCheck %s --check-prefixes=BE + +define i16 @loadCombine_2consecutive(i8* %p) { +; +; LE-LABEL: @loadCombine_2consecutive( +; LE-NEXT: [[TMP1:%.*]] = bitcast i8* [[P:%.*]] to i16* +; LE-NEXT: [[L1:%.*]] = load i16, i16* [[TMP1]], align 1 +; LE-NEXT: ret i16 [[L1]] +; +; BE-LABEL: @loadCombine_2consecutive( +; BE-NEXT: [[P1:%.*]] = getelementptr i8, i8* [[P:%.*]], i32 1 +; BE-NEXT: [[L1:%.*]] = load i8, i8* [[P]], align 1 +; BE-NEXT: [[L2:%.*]] = load i8, i8* [[P1]], align 1 +; BE-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i16 +; BE-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i16 +; BE-NEXT: [[S2:%.*]] = shl i16 [[E2]], 8 +; BE-NEXT: [[O1:%.*]] = or i16 [[E1]], [[S2]] +; BE-NEXT: ret i16 [[O1]] +; + %p1 = getelementptr i8, i8* %p, i32 1 + %l1 = load i8, i8* %p + %l2 = load i8, i8* %p1 + %e1 = zext i8 %l1 to i16 + %e2 = zext i8 %l2 to i16 + %s2 = shl i16 %e2, 8 + %o1 = or i16 %e1, %s2 + ret i16 %o1 +}