Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -786,9 +786,9 @@ return SDValue(); } if (N1.hasOneUse()) { - // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one + // reassoc. (op x, (op y, c1)) -> (op (op x, y), c1) iff x+c1 has one // use - SDValue OpNode = DAG.getNode(Opc, SDLoc(N0), VT, N1.getOperand(0), N0); + SDValue OpNode = DAG.getNode(Opc, SDLoc(N0), VT, N0, N1.getOperand(0)); if (!OpNode.getNode()) return SDValue(); AddToWorklist(OpNode.getNode()); Index: test/CodeGen/R600/dagcombine-reassociate-bug.ll =================================================================== --- /dev/null +++ test/CodeGen/R600/dagcombine-reassociate-bug.ll @@ -0,0 +1,33 @@ +; RUN: llc -march=amdgcn -mcpu=SI -verify-machineinstrs < %s | FileCheck %s + +; Test for a bug where DAGCombiner::ReassociateOps() was creating adds +; with offset in the first operand and base pointers in the second. + +; CHECK-LABEL: {{^}}store_same_base_ptr: +; CHECK: buffer_store_dword v{{[0-9]+}}, [[VADDR:v\[[0-9]+:[0-9]+\]]], [[SADDR:s\[[0-9]+:[0-9]+\]]] +; CHECK: buffer_store_dword v{{[0-9]+}}, [[VADDR]], [[SADDR]] +; CHECK: buffer_store_dword v{{[0-9]+}}, [[VADDR]], [[SADDR]] +; CHECK: buffer_store_dword v{{[0-9]+}}, [[VADDR]], [[SADDR]] + +define void @store_same_base_ptr(i32 addrspace(1)* %out) { +entry: + %id = call i32 @llvm.r600.read.tidig.x() #0 + %offset = sext i32 %id to i64 + %offset0 = add i64 %offset, 1027 + %ptr0 = getelementptr i32 addrspace(1)* %out, i64 %offset0 + store i32 3, i32 addrspace(1)* %ptr0 + %offset1 = add i64 %offset, 1026 + %ptr1 = getelementptr i32 addrspace(1)* %out, i64 %offset1 + store i32 2, i32 addrspace(1)* %ptr1 + %offset2 = add i64 %offset, 1025 + %ptr2 = getelementptr i32 addrspace(1)* %out, i64 %offset2 + store i32 1, i32 addrspace(1)* %ptr2 + %offset3 = add i64 %offset, 1024 + %ptr3 = getelementptr i32 addrspace(1)* %out, i64 %offset3 + store i32 0, i32 addrspace(1)* %ptr3 + ret void +} + +declare i32 @llvm.r600.read.tidig.x() #0 + +attributes #0 = { readnone }