From a377183cff12e7b95689f0d44e10eb595fe0519b Mon Sep 17 00:00:00 2001 From: Serguei Katkov Date: Tue, 9 Jan 2018 04:37:06 +0000 Subject: [PATCH] [CGP] Fix Complex addressing mode for offset If the offset is differ in two addressing mode we can continue only if ScaleReg is not set due to we will use it as merge of different offsets. It should fix PR35799 and PR35805. Reviewers: john.brawn, reames Reviewed By: reames Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D41227 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@322056 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenPrepare.cpp | 7 ++++++- .../X86/sink-addrmode-select.ll | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp index 9dc1ab4e6bb..26ca8d4ee88 100644 --- a/lib/CodeGen/CodeGenPrepare.cpp +++ b/lib/CodeGen/CodeGenPrepare.cpp @@ -2700,8 +2700,13 @@ public: // we still need to collect it due to original value is different. // And later we will need all original values as anchors during // finding the common Phi node. + // We also must reject the case when base offset is different and + // scale reg is not null, we cannot handle this case due to merge of + // different offsets will be used as ScaleReg. if (DifferentField != ExtAddrMode::MultipleFields && - DifferentField != ExtAddrMode::ScaleField) { + DifferentField != ExtAddrMode::ScaleField && + (DifferentField != ExtAddrMode::BaseOffsField || + !NewAddrMode.ScaledReg)) { AddrModes.emplace_back(NewAddrMode); return true; } diff --git a/test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll b/test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll new file mode 100644 index 00000000000..b153a8b1e53 --- /dev/null +++ b/test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll @@ -0,0 +1,19 @@ +; RUN: opt -S -codegenprepare -disable-complex-addr-modes=false -addr-sink-new-select=true %s | FileCheck %s --check-prefix=CHECK +target datalayout = +"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + +; Select when both offset and scale reg are present. +define i64 @test1(i1 %c, i64* %b, i64 %scale) { +; CHECK-LABEL: @test1 +entry: +; CHECK-LABEL: entry: + %g = getelementptr inbounds i64, i64* %b, i64 %scale + %g1 = getelementptr inbounds i64, i64* %g, i64 8 + %g2 = getelementptr inbounds i64, i64* %g, i64 16 + %s = select i1 %c, i64* %g1, i64* %g2 +; CHECK-NOT: sunkaddr + %v = load i64 , i64* %s, align 8 + ret i64 %v +} +